summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-03-05 10:44:04 +0100
committerLars Knoll <lars.knoll@nokia.com>2012-03-05 10:44:48 +0100
commitd51abed57a8f677a0d4eac57fd3f16bd4662190a (patch)
treeb3e173db4b72edbff6cb8dcc203c3d4526a1b51b
parent07ae18f96e87a2db40ae014f28893f1080efa7ae (diff)
parent0862d7f78af978cf513097b3bdc33cd8096dee75 (diff)
Merge remote-tracking branch 'origin/master' into api_changes
-rwxr-xr-xconfig.tests/unix/doubleformat.test63
-rw-r--r--config.tests/unix/doubleformat/doubleformattest.pro3
-rwxr-xr-xconfig.tests/unix/endian.test60
-rw-r--r--config.tests/unix/endian/endiantest.pro3
-rwxr-xr-xconfigure204
-rw-r--r--configure.bat6
-rw-r--r--dist/README2
-rw-r--r--dist/changes-5.0.03
-rw-r--r--doc/src/corelib/containers.qdoc196
-rw-r--r--doc/src/corelib/json.qdoc12
-rw-r--r--doc/src/corelib/objectmodel/metaobjects.qdoc18
-rw-r--r--doc/src/corelib/objectmodel/object.qdoc26
-rw-r--r--doc/src/corelib/objectmodel/properties.qdoc22
-rw-r--r--doc/src/corelib/threads-basics.qdoc88
-rw-r--r--doc/src/corelib/threads.qdoc132
-rw-r--r--doc/src/examples/addressbook.qdoc12
-rw-r--r--doc/src/examples/affine.qdoc8
-rw-r--r--doc/src/examples/arrowpad.qdoc36
-rw-r--r--doc/src/examples/basicdrawing.qdoc30
-rw-r--r--doc/src/examples/basicgraphicslayouts.qdoc6
-rw-r--r--doc/src/examples/blockingfortuneclient.qdoc4
-rw-r--r--doc/src/examples/boxes.qdoc6
-rw-r--r--doc/src/examples/cachedtable.qdoc8
-rw-r--r--doc/src/examples/calculator.qdoc40
-rw-r--r--doc/src/examples/calendar.qdoc8
-rw-r--r--doc/src/examples/calendarwidget.qdoc40
-rw-r--r--doc/src/examples/charactermap.qdoc4
-rw-r--r--doc/src/examples/chart.qdoc6
-rw-r--r--doc/src/examples/classwizard.qdoc14
-rw-r--r--doc/src/examples/coloreditorfactory.qdoc6
-rw-r--r--doc/src/examples/completer.qdoc4
-rw-r--r--doc/src/examples/composition.qdoc6
-rw-r--r--doc/src/examples/concentriccircles.qdoc4
-rw-r--r--doc/src/examples/cube.qdoc4
-rw-r--r--doc/src/examples/customsortfiltermodel.qdoc4
-rw-r--r--doc/src/examples/dbscreen.qdoc26
-rw-r--r--doc/src/examples/diagramscene.qdoc20
-rw-r--r--doc/src/examples/drilldown.qdoc6
-rw-r--r--doc/src/examples/dropsite.qdoc16
-rw-r--r--doc/src/examples/editabletreemodel.qdoc40
-rw-r--r--doc/src/examples/elasticnodes.qdoc6
-rw-r--r--doc/src/examples/fortuneclient.qdoc8
-rw-r--r--doc/src/examples/fridgemagnets.qdoc4
-rw-r--r--doc/src/examples/gradients.qdoc6
-rw-r--r--doc/src/examples/hellogl.qdoc6
-rw-r--r--doc/src/examples/icons.qdoc92
-rw-r--r--doc/src/examples/imagecomposition.qdoc6
-rw-r--r--doc/src/examples/imageviewer.qdoc26
-rw-r--r--doc/src/examples/licensewizard.qdoc20
-rw-r--r--doc/src/examples/maemovibration.qdoc8
-rw-r--r--doc/src/examples/mandelbrot.qdoc16
-rw-r--r--doc/src/examples/mousecalibration.qdoc4
-rw-r--r--doc/src/examples/moveblocks.qdoc8
-rw-r--r--doc/src/examples/orderform.qdoc86
-rw-r--r--doc/src/examples/overpainting.qdoc24
-rw-r--r--doc/src/examples/padnavigator.qdoc44
-rw-r--r--doc/src/examples/painterpaths.qdoc4
-rw-r--r--doc/src/examples/pixelator.qdoc4
-rw-r--r--doc/src/examples/plugandpaint.qdoc22
-rw-r--r--doc/src/examples/rogue.qdoc4
-rw-r--r--doc/src/examples/screenshot.qdoc12
-rw-r--r--doc/src/examples/scribble.qdoc20
-rw-r--r--doc/src/examples/simpletreemodel.qdoc16
-rw-r--r--doc/src/examples/sipdialog.qdoc8
-rw-r--r--doc/src/examples/sliders.qdoc12
-rw-r--r--doc/src/examples/stardelegate.qdoc10
-rw-r--r--doc/src/examples/styles.qdoc18
-rw-r--r--doc/src/examples/svgalib.qdoc20
-rw-r--r--doc/src/examples/syntaxhighlighter.qdoc4
-rw-r--r--doc/src/examples/tablet.qdoc8
-rw-r--r--doc/src/examples/tetrix.qdoc6
-rw-r--r--doc/src/examples/textfinder.qdoc8
-rw-r--r--doc/src/examples/tooltips.qdoc4
-rw-r--r--doc/src/examples/transformations.qdoc6
-rw-r--r--doc/src/examples/trollprint.qdoc30
-rw-r--r--doc/src/examples/undoframework.qdoc12
-rw-r--r--doc/src/examples/wiggly.qdoc4
-rw-r--r--doc/src/examples/windowflags.qdoc4
-rw-r--r--doc/src/gui/coordsys.qdoc116
-rw-r--r--doc/src/gui/paintsystem.qdoc82
-rw-r--r--doc/src/network/files-and-resources/datastreamformat.qdoc620
-rw-r--r--doc/src/network/network-programming/bearermanagement.qdoc44
-rw-r--r--doc/src/printsupport/printing.qdoc16
-rw-r--r--doc/src/sql/sql-programming/qsqldatatype-table.qdoc708
-rw-r--r--doc/src/sql/sql-programming/sql-driver.qdoc108
-rw-r--r--doc/src/sql/sql-programming/sql-programming.qdoc36
-rw-r--r--doc/src/widgets/addressbook-fr.qdoc56
-rw-r--r--doc/src/widgets/addressbook.qdoc56
-rw-r--r--doc/src/widgets/modelview.qdoc580
-rw-r--r--doc/src/widgets/widgets-and-layouts/focus.qdoc14
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc56
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc58
-rw-r--r--doc/src/widgets/widgets-and-layouts/gallery.qdoc18
-rw-r--r--doc/src/widgets/widgets-and-layouts/layout.qdoc62
-rw-r--r--doc/src/widgets/widgets-and-layouts/styles.qdoc798
-rw-r--r--doc/src/widgets/widgets-and-layouts/stylesheet.qdoc1562
-rw-r--r--doc/src/widgets/widgets-and-layouts/widgets.qdoc32
-rw-r--r--doc/src/widgets/widgets-tutorial.qdoc30
-rw-r--r--doc/src/widgets/windows-and-dialogs/mainwindow.qdoc10
-rw-r--r--examples/opengl/cube/cube.pro9
-rw-r--r--examples/webkit/webkit-guide/_index.html2
-rw-r--r--mkspecs/features/create_cmake.prf2
-rw-r--r--mkspecs/features/default_pre.prf4
-rw-r--r--mkspecs/features/qt_module_config.prf20
-rw-r--r--mkspecs/features/testcocoon.prf2
-rw-r--r--mkspecs/macx-xcode/qmake.conf2
-rw-r--r--mkspecs/unsupported/win32-g++-cross/qmake.conf1
-rw-r--r--mkspecs/win32-g++/qmake.conf1
-rw-r--r--qmake/Makefile.unix2
-rw-r--r--qmake/Makefile.win322
-rw-r--r--qmake/Makefile.win32-g++272
-rw-r--r--qmake/Makefile.win32-g++-sh343
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp243
-rw-r--r--qmake/generators/makefile.cpp4
-rw-r--r--qmake/generators/metamakefile.cpp18
-rw-r--r--qmake/generators/projectgenerator.cpp2
-rw-r--r--qmake/generators/win32/winmakefile.cpp18
-rw-r--r--qmake/main.cpp2
-rw-r--r--qmake/option.cpp84
-rw-r--r--qmake/option.h7
-rw-r--r--qmake/project.cpp110
-rw-r--r--qmake/project.h13
-rw-r--r--qmake/property.cpp4
-rw-r--r--src/3rdparty/pcre/AUTHORS45
-rw-r--r--src/3rdparty/pcre/COPYING5
-rw-r--r--src/3rdparty/pcre/LICENCE92
-rw-r--r--src/3rdparty/pcre/pcre.h503
-rw-r--r--src/3rdparty/pcre/pcre16_byte_order.c45
-rw-r--r--src/3rdparty/pcre/pcre16_chartables.c45
-rw-r--r--src/3rdparty/pcre/pcre16_compile.c45
-rw-r--r--src/3rdparty/pcre/pcre16_config.c45
-rw-r--r--src/3rdparty/pcre/pcre16_dfa_exec.c45
-rw-r--r--src/3rdparty/pcre/pcre16_exec.c45
-rw-r--r--src/3rdparty/pcre/pcre16_fullinfo.c45
-rw-r--r--src/3rdparty/pcre/pcre16_get.c45
-rw-r--r--src/3rdparty/pcre/pcre16_globals.c45
-rw-r--r--src/3rdparty/pcre/pcre16_jit_compile.c45
-rw-r--r--src/3rdparty/pcre/pcre16_maketables.c45
-rw-r--r--src/3rdparty/pcre/pcre16_newline.c45
-rw-r--r--src/3rdparty/pcre/pcre16_ord2utf16.c95
-rw-r--r--src/3rdparty/pcre/pcre16_refcount.c45
-rw-r--r--src/3rdparty/pcre/pcre16_string_utils.c45
-rw-r--r--src/3rdparty/pcre/pcre16_study.c45
-rw-r--r--src/3rdparty/pcre/pcre16_tables.c45
-rw-r--r--src/3rdparty/pcre/pcre16_ucd.c45
-rw-r--r--src/3rdparty/pcre/pcre16_utf16_utils.c129
-rw-r--r--src/3rdparty/pcre/pcre16_valid_utf16.c146
-rw-r--r--src/3rdparty/pcre/pcre16_version.c45
-rw-r--r--src/3rdparty/pcre/pcre16_xclass.c45
-rw-r--r--src/3rdparty/pcre/pcre_byte_order.c288
-rw-r--r--src/3rdparty/pcre/pcre_chartables.c198
-rw-r--r--src/3rdparty/pcre/pcre_compile.c8162
-rw-r--r--src/3rdparty/pcre/pcre_config.c170
-rw-r--r--src/3rdparty/pcre/pcre_dfa_exec.c3490
-rw-r--r--src/3rdparty/pcre/pcre_exec.c6960
-rw-r--r--src/3rdparty/pcre/pcre_fullinfo.c202
-rw-r--r--src/3rdparty/pcre/pcre_get.c587
-rw-r--r--src/3rdparty/pcre/pcre_globals.c84
-rw-r--r--src/3rdparty/pcre/pcre_internal.h2332
-rw-r--r--src/3rdparty/pcre/pcre_jit_compile.c6915
-rw-r--r--src/3rdparty/pcre/pcre_maketables.c148
-rw-r--r--src/3rdparty/pcre/pcre_newline.c184
-rw-r--r--src/3rdparty/pcre/pcre_ord2utf8.c97
-rw-r--r--src/3rdparty/pcre/pcre_refcount.c89
-rw-r--r--src/3rdparty/pcre/pcre_string_utils.c168
-rw-r--r--src/3rdparty/pcre/pcre_study.c1527
-rw-r--r--src/3rdparty/pcre/pcre_tables.c568
-rw-r--r--src/3rdparty/pcre/pcre_ucd.c2981
-rw-r--r--src/3rdparty/pcre/pcre_valid_utf8.c299
-rw-r--r--src/3rdparty/pcre/pcre_version.c95
-rw-r--r--src/3rdparty/pcre/pcre_xclass.c198
-rw-r--r--src/3rdparty/pcre/sljit/sljitConfig.h96
-rw-r--r--src/3rdparty/pcre/sljit/sljitConfigInternal.h424
-rw-r--r--src/3rdparty/pcre/sljit/sljitExecAllocator.c277
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.c1594
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.h853
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c1913
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeARM_v5.c2424
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c405
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c1829
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativePPC_32.c262
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativePPC_64.c428
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativePPC_common.c1872
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_32.c517
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_64.c842
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_common.c2858
-rw-r--r--src/3rdparty/pcre/sljit/sljitUtils.c244
-rw-r--r--src/3rdparty/pcre/ucp.h165
-rw-r--r--src/concurrent/qtconcurrentexception.cpp8
-rw-r--r--src/concurrent/qtconcurrentrun.cpp6
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in3
-rw-r--r--src/corelib/animation/qvariantanimation.cpp24
-rw-r--r--src/corelib/codecs/codecs.qdoc56
-rw-r--r--src/corelib/codecs/qtextcodec.cpp86
-rw-r--r--src/corelib/global/qglobal.cpp14
-rw-r--r--src/corelib/global/qlogging.cpp2
-rw-r--r--src/corelib/global/qnamespace.qdoc54
-rw-r--r--src/corelib/global/qnumeric_p.h42
-rw-r--r--src/corelib/global/qprocessordetection.h76
-rw-r--r--src/corelib/io/qdatastream.cpp97
-rw-r--r--src/corelib/io/qdir.cpp20
-rw-r--r--src/corelib/io/qfile.cpp8
-rw-r--r--src/corelib/io/qfileinfo.cpp6
-rw-r--r--src/corelib/io/qiodevice.cpp16
-rw-r--r--src/corelib/io/qprocess.cpp18
-rw-r--r--src/corelib/io/qresource.cpp8
-rw-r--r--src/corelib/io/qsettings.cpp126
-rw-r--r--src/corelib/io/qtextstream.cpp68
-rw-r--r--src/corelib/io/qurl.cpp16
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp82
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp20
-rw-r--r--src/corelib/json/qjson_p.h3
-rw-r--r--src/corelib/json/qjsonarray.cpp4
-rw-r--r--src/corelib/json/qjsonobject.cpp4
-rw-r--r--src/corelib/json/qjsonvalue.cpp32
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp24
-rw-r--r--src/corelib/kernel/qcore_mac_p.h23
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp10
-rw-r--r--src/corelib/kernel/qeventloop.cpp6
-rw-r--r--src/corelib/kernel/qmetaobject.cpp26
-rw-r--r--src/corelib/kernel/qmimedata.cpp18
-rw-r--r--src/corelib/kernel/qobject.cpp28
-rw-r--r--src/corelib/kernel/qobject.h9
-rw-r--r--src/corelib/kernel/qobject_p.h3
-rw-r--r--src/corelib/kernel/qobjectdefs.h6
-rw-r--r--src/corelib/kernel/qpointer.cpp4
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp6
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp16
-rw-r--r--src/corelib/kernel/qsystemsemaphore.cpp8
-rw-r--r--src/corelib/kernel/qtranslator.cpp56
-rw-r--r--src/corelib/kernel/qvariant.cpp44
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp4
-rw-r--r--src/corelib/plugin/qlibrary.cpp12
-rw-r--r--src/corelib/plugin/qpluginloader.cpp4
-rw-r--r--src/corelib/plugin/quuid.cpp168
-rw-r--r--src/corelib/thread/qatomic.cpp72
-rw-r--r--src/corelib/thread/qsemaphore.cpp4
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/corelib/thread/qthreadstorage.cpp4
-rw-r--r--src/corelib/thread/qwaitcondition.qdoc8
-rw-r--r--src/corelib/tools/qalgorithms.qdoc14
-rw-r--r--src/corelib/tools/qbytearray.cpp26
-rw-r--r--src/corelib/tools/qcryptographichash.cpp9
-rw-r--r--src/corelib/tools/qdatetime.cpp406
-rw-r--r--src/corelib/tools/qhash.cpp6
-rw-r--r--src/corelib/tools/qline.cpp20
-rw-r--r--src/corelib/tools/qlinkedlist.cpp6
-rw-r--r--src/corelib/tools/qlist.cpp6
-rw-r--r--src/corelib/tools/qlocale.cpp22
-rw-r--r--src/corelib/tools/qlocale.qdoc12
-rw-r--r--src/corelib/tools/qlocale_tools.cpp44
-rw-r--r--src/corelib/tools/qlocale_tools_p.h4
-rw-r--r--src/corelib/tools/qmap.cpp6
-rw-r--r--src/corelib/tools/qpair.h6
-rw-r--r--src/corelib/tools/qrect.cpp48
-rw-r--r--src/corelib/tools/qregexp.cpp411
-rw-r--r--src/corelib/tools/qringbuffer_p.h2
-rw-r--r--src/corelib/tools/qscopedpointer.cpp6
-rw-r--r--src/corelib/tools/qshareddata.cpp4
-rw-r--r--src/corelib/tools/qsize.cpp12
-rw-r--r--src/corelib/tools/qstring.cpp32
-rw-r--r--src/corelib/tools/qstringlist.cpp2
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc6
-rw-r--r--src/corelib/tools/qvector.cpp8
-rw-r--r--src/dbus/qdbusmessage.cpp8
-rw-r--r--src/dbus/qdbuspendingreply.cpp4
-rw-r--r--src/dbus/qdbusservicewatcher.cpp6
-rw-r--r--src/dbus/qdbusutil.cpp24
-rw-r--r--src/gui/accessible/qaccessible.cpp32
-rw-r--r--src/gui/accessible/qaccessible.h2
-rw-r--r--src/gui/accessible/qaccessible2.cpp16
-rw-r--r--src/gui/image/image.pri7
-rw-r--r--src/gui/image/qimage.cpp84
-rw-r--r--src/gui/image/qimagereader.cpp34
-rw-r--r--src/gui/image/qimagewriter.cpp16
-rw-r--r--src/gui/image/qpixmap.cpp42
-rw-r--r--src/gui/image/qvolatileimage.cpp285
-rw-r--r--src/gui/image/qvolatileimage_p.h100
-rw-r--r--src/gui/kernel/kernel.pri7
-rw-r--r--src/gui/kernel/qclipboard.cpp12
-rw-r--r--src/gui/kernel/qcursor.cpp98
-rw-r--r--src/gui/kernel/qdnd.cpp402
-rw-r--r--src/gui/kernel/qdnd_p.h87
-rw-r--r--src/gui/kernel/qdrag.cpp99
-rw-r--r--src/gui/kernel/qdrag.h5
-rw-r--r--src/gui/kernel/qevent.cpp53
-rw-r--r--src/gui/kernel/qguiapplication.cpp99
-rw-r--r--src/gui/kernel/qguiapplication_p.h6
-rw-r--r--src/gui/kernel/qkeysequence.cpp140
-rw-r--r--src/gui/kernel/qpalette.cpp6
-rw-r--r--src/gui/kernel/qplatformdrag_qpa.cpp187
-rw-r--r--src/gui/kernel/qplatformdrag_qpa.h49
-rw-r--r--src/gui/kernel/qplatformnativeinterface_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.h11
-rw-r--r--src/gui/kernel/qplatformscreenpageflipper_qpa.cpp (renamed from config.tests/unix/doubleformat/doubleformattest.cpp)51
-rw-r--r--src/gui/kernel/qplatformscreenpageflipper_qpa.h (renamed from src/gui/image/qvolatileimagedata_p.h)63
-rw-r--r--src/gui/kernel/qplatformtheme_qpa.cpp5
-rw-r--r--src/gui/kernel/qplatformtheme_qpa.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp9
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h6
-rw-r--r--src/gui/math3d/qgenericmatrix.cpp6
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp6
-rw-r--r--src/gui/math3d/qvector2d.cpp2
-rw-r--r--src/gui/math3d/qvector3d.cpp2
-rw-r--r--src/gui/math3d/qvector4d.cpp2
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp20
-rw-r--r--src/gui/painting/qbrush.cpp74
-rw-r--r--src/gui/painting/qcolor.cpp26
-rw-r--r--src/gui/painting/qmatrix.cpp12
-rw-r--r--src/gui/painting/qpaintengine_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp272
-rw-r--r--src/gui/painting/qpainterpath.cpp60
-rw-r--r--src/gui/painting/qpen.cpp60
-rw-r--r--src/gui/painting/qregion.cpp8
-rw-r--r--src/gui/painting/qtransform.cpp12
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp20
-rw-r--r--src/gui/text/qfont.cpp103
-rw-r--r--src/gui/text/qfont_p.h5
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp2
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontengine_qpa.cpp85
-rw-r--r--src/gui/text/qfontengine_qpa_p.h5
-rw-r--r--src/gui/text/qfontmetrics.cpp78
-rw-r--r--src/gui/text/qrawfont.cpp6
-rw-r--r--src/gui/text/qrawfont.h1
-rw-r--r--src/gui/text/qtextcursor.cpp10
-rw-r--r--src/gui/text/qtextdocument.cpp14
-rw-r--r--src/gui/text/qtextdocumentwriter.cpp8
-rw-r--r--src/gui/text/qtextengine.cpp175
-rw-r--r--src/gui/text/qtextengine_p.h8
-rw-r--r--src/gui/text/qtextlayout.cpp44
-rw-r--r--src/gui/text/qtextlayout.h7
-rw-r--r--src/gui/text/qtextlist.cpp2
-rw-r--r--src/gui/text/qtexttable.cpp12
-rw-r--r--src/gui/util/qvalidator.cpp16
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp8
-rw-r--r--src/network/access/qnetworkcookie.cpp4
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp2
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp2
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp42
-rw-r--r--src/network/bearer/qnetworksession.cpp18
-rw-r--r--src/network/kernel/kernel.pri1
-rw-r--r--src/network/kernel/qauthenticator.cpp14
-rw-r--r--src/network/kernel/qdnslookup_win.cpp38
-rw-r--r--src/network/kernel/qhostaddress.cpp14
-rw-r--r--src/network/kernel/qnetworkproxy.cpp66
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp16
-rw-r--r--src/network/socket/qabstractsocket.cpp34
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp12
-rw-r--r--src/network/socket/qtcpsocket.cpp2
-rw-r--r--src/network/ssl/qsslcertificateextension.cpp54
-rw-r--r--src/network/ssl/qsslconfiguration.cpp20
-rw-r--r--src/network/ssl/qsslsocket.cpp10
-rw-r--r--src/opengl/qgl.cpp110
-rw-r--r--src/opengl/qglframebufferobject.cpp18
-rw-r--r--src/opengl/qglpixelbuffer.cpp6
-rw-r--r--src/platformsupport/dnd/dnd.pri6
-rw-r--r--src/platformsupport/dnd/qshapedpixmapdndwindow.cpp (renamed from src/gui/image/qvolatileimagedata.cpp)82
-rw-r--r--src/platformsupport/dnd/qshapedpixmapdndwindow_p.h (renamed from config.tests/unix/endian/endiantest.cpp)48
-rw-r--r--src/platformsupport/dnd/qsimpledrag.cpp318
-rw-r--r--src/platformsupport/dnd/qsimpledrag_p.h64
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration.cpp2
-rw-r--r--src/platformsupport/glxconvenience/glxconvenience.pri1
-rw-r--r--src/platformsupport/udev/udev.pri1
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmouse.cpp23
-rw-r--r--src/plugins/generic/evdevtouch/README12
-rw-r--r--src/plugins/generic/evdevtouch/evdevtouch.pro4
-rw-r--r--src/plugins/generic/evdevtouch/qevdevtouch.cpp89
-rw-r--r--src/plugins/generic/evdevtouch/qevdevtouch.h8
-rw-r--r--src/plugins/platforms/blackberry/qbbclipboard.cpp184
-rw-r--r--src/plugins/platforms/blackberry/qbbclipboard.h5
-rw-r--r--src/plugins/platforms/blackberry/qbbscreen.cpp2
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.h54
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm145
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm15
-rw-r--r--src/plugins/platforms/cocoa/qmacdefines_mac.h11
-rw-r--r--src/plugins/platforms/windows/main.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsaccessibility.cpp120
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp278
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp16
-rw-r--r--src/plugins/platforms/xcb/README4
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp18
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp55
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp438
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h45
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbsharedbuffermanager.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp43
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp7
-rw-r--r--src/plugins/platforms/xcb/xcb.pro2
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog.cpp4
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp6
-rw-r--r--src/printsupport/kernel/qprinter.cpp10
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.cpp4
-rw-r--r--src/sql/kernel/qsqldatabase.cpp174
-rw-r--r--src/sql/kernel/qsqldriver.cpp8
-rw-r--r--src/sql/kernel/qsqlquery.cpp44
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp14
-rw-r--r--src/src.pro4
-rw-r--r--src/testlib/qsignalspy.qdoc2
-rw-r--r--src/testlib/qtestcase.cpp52
-rw-r--r--src/tools/tools.pro4
-rw-r--r--src/widgets/dialogs/qdialog.cpp4
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp8
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp8
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp164
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp8
-rw-r--r--src/widgets/dialogs/qwizard.cpp101
-rw-r--r--src/widgets/effects/qgraphicseffect.cpp18
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout.cpp6
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp78
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicslayout.cpp22
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp68
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp16
-rw-r--r--src/widgets/graphicsview/qgraphicsscene_p.h2
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp156
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp38
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.cpp32
-rw-r--r--src/widgets/itemviews/qdirmodel.cpp10
-rw-r--r--src/widgets/itemviews/qheaderview.cpp116
-rw-r--r--src/widgets/itemviews/qheaderview_p.h20
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp58
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp22
-rw-r--r--src/widgets/itemviews/qlistview.cpp12
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp12
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp58
-rw-r--r--src/widgets/itemviews/qtableview.cpp16
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp12
-rw-r--r--src/widgets/itemviews/qtreeview.cpp40
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp14
-rw-r--r--src/widgets/kernel/qapplication.cpp92
-rw-r--r--src/widgets/kernel/qapplication_p.h4
-rw-r--r--src/widgets/kernel/qboxlayout.cpp12
-rw-r--r--src/widgets/kernel/qformlayout.cpp34
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp6
-rw-r--r--src/widgets/kernel/qgesturemanager_p.h4
-rw-r--r--src/widgets/kernel/qicon.cpp4
-rw-r--r--src/widgets/kernel/qiconengineplugin.cpp2
-rw-r--r--src/widgets/kernel/qlayout.cpp4
-rw-r--r--src/widgets/kernel/qlayoutitem.cpp30
-rw-r--r--src/widgets/kernel/qwidget.cpp132
-rw-r--r--src/widgets/kernel/qwidgetaction.cpp10
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp10
-rw-r--r--src/widgets/styles/qgtkstyle_p.h2
-rw-r--r--src/widgets/styles/qmacstyle.qdoc6
-rw-r--r--src/widgets/styles/qstyle.cpp342
-rw-r--r--src/widgets/styles/qstyleoption.cpp8
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp7
-rw-r--r--src/widgets/util/qcompleter.cpp2
-rw-r--r--src/widgets/util/qscrollerproperties.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp6
-rw-r--r--src/widgets/util/qundostack.cpp8
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp20
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp8
-rw-r--r--src/widgets/widgets/qabstractslider.cpp40
-rw-r--r--src/widgets/widgets/qabstractslider.h3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp28
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp16
-rw-r--r--src/widgets/widgets/qcheckbox.cpp16
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp60
-rw-r--r--src/widgets/widgets/qdial.cpp8
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp42
-rw-r--r--src/widgets/widgets/qdockwidget.cpp8
-rw-r--r--src/widgets/widgets/qframe.cpp6
-rw-r--r--src/widgets/widgets/qgroupbox.cpp20
-rw-r--r--src/widgets/widgets/qlabel.cpp48
-rw-r--r--src/widgets/widgets/qlcdnumber.cpp18
-rw-r--r--src/widgets/widgets/qlineedit.cpp104
-rw-r--r--src/widgets/widgets/qmainwindow.cpp8
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qmenu.cpp8
-rw-r--r--src/widgets/widgets/qmenubar.cpp32
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp82
-rw-r--r--src/widgets/widgets/qprogressbar.cpp12
-rw-r--r--src/widgets/widgets/qpushbutton.cpp30
-rw-r--r--src/widgets/widgets/qradiobutton.cpp12
-rw-r--r--src/widgets/widgets/qscrollarea.cpp6
-rw-r--r--src/widgets/widgets/qscrollbar.cpp50
-rw-r--r--src/widgets/widgets/qsizegrip.cpp4
-rw-r--r--src/widgets/widgets/qslider.cpp42
-rw-r--r--src/widgets/widgets/qspinbox.cpp12
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp2
-rw-r--r--src/widgets/widgets/qstatusbar.cpp6
-rw-r--r--src/widgets/widgets/qtabbar.cpp18
-rw-r--r--src/widgets/widgets/qtabwidget.cpp20
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp32
-rw-r--r--src/widgets/widgets/qtextedit.cpp76
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp4
-rw-r--r--src/widgets/widgets/qwidgetanimator_p.h4
-rw-r--r--src/widgets/widgets/qworkspace.cpp4
-rw-r--r--src/xml/dom/qdom.cpp114
-rw-r--r--src/xml/sax/qxml.cpp72
-rw-r--r--tests/auto/corelib/global/qlogging/test/test.pro3
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp9
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro2
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp9
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro2
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp4
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro2
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp160
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h10
-rw-r--r--tests/auto/corelib/tools/qchar/tst_qchar.cpp4
-rw-r--r--tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro3
-rw-r--r--tests/auto/corelib/tools/qlocale/test/test.pro4
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp4
-rw-r--r--tests/auto/corelib/tools/qregexp/tst_qregexp.cpp290
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp11
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp24
-rw-r--r--tests/auto/gui/image/image.pro1
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp4
-rw-r--r--tests/auto/gui/image/qpixmap/qpixmap.pro2
-rw-r--r--tests/auto/gui/image/qvolatileimage/qvolatileimage.pro6
-rw-r--r--tests/auto/gui/image/qvolatileimage/tst_qvolatileimage.cpp206
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp13
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp3
-rw-r--r--tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp12
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp2
-rw-r--r--tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp2
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp36
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp10
-rw-r--r--tests/auto/other/networkselftest/tst_networkselftest.cpp2
-rw-r--r--tests/auto/testlib/selftests/counting/tst_counting.cpp1
-rw-r--r--tests/auto/testlib/selftests/expected_counting.lightxml32
-rw-r--r--tests/auto/testlib/selftests/expected_counting.txt32
-rw-r--r--tests/auto/testlib/selftests/expected_counting.xml32
-rw-r--r--tests/auto/testlib/selftests/expected_fatal.txt6
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.lightxml150
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.txt69
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.xml153
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.xunitxml64
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.lightxml222
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.txt105
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.xml225
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.xunitxml101
-rw-r--r--tests/auto/testlib/selftests/selftests.pri2
-rw-r--r--tests/auto/testlib/selftests/selftests.qrc17
-rw-r--r--tests/auto/testlib/selftests/tst_selftests.cpp10
-rw-r--r--tests/auto/testlib/selftests/verbose1/verbose1.pro10
-rw-r--r--tests/auto/testlib/selftests/verbose2/verbose2.pro10
-rw-r--r--tests/auto/tools/qmake/testcompiler.cpp25
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro2
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp90
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp4
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp62
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp3
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp13
-rw-r--r--tests/benchmarks/corelib/tools/qhash/main.cpp105
-rw-r--r--tests/benchmarks/corelib/tools/qhash/main.h8
-rw-r--r--tests/benchmarks/corelib/tools/qhash/outofline.cpp48
-rw-r--r--tools/configure/Makefile.win323
-rw-r--r--tools/configure/configureapp.cpp51
-rw-r--r--tools/configure/configureapp.h1
581 files changed, 66267 insertions, 11075 deletions
diff --git a/config.tests/unix/doubleformat.test b/config.tests/unix/doubleformat.test
deleted file mode 100755
index 996855372b..0000000000
--- a/config.tests/unix/doubleformat.test
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-QMKSPEC=$1
-VERBOSE=$2
-SRCDIR=$3
-OUTDIR=$4
-
-# debuggery
-[ "$VERBOSE" = "yes" ] && echo "Determining floating point word-order... ($*)"
-
-# build and run a test program
-test -d "$OUTDIR/config.tests/unix/doubleformat" || mkdir -p "$OUTDIR/config.tests/unix/doubleformat"
-"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/config.tests/unix/doubleformat/doubleformattest.pro" -o "$OUTDIR/config.tests/unix/doubleformat/Makefile" >/dev/null 2>&1
-cd "$OUTDIR/config.tests/unix/doubleformat"
-
-DOUBLEFORMAT="UNKNOWN"
-[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1
-
-if [ -f ./doubleformattest ]; then
- : # nop
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown floating point format!"
- exit 2
-fi
-
-# LE: strings | grep 0123ABCD0123ABCD
-# BE: strings | grep DCBA3210DCBA3210
-#
-# LE arm-swapped-dword-order: strings | grep ABCD0123ABCD0123
-# BE arm-swapped-dword-order: strings | grep 3210DCBA3210DCBA (untested)
-
-
-if strings ./doubleformattest | grep "0123ABCD0123ABCD" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Normal little endian format"
- DOUBLEFORMAT="LITTLE"
-elif strings ./doubleformattest | grep "ABCD0123ABCD0123" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Swapped little endian format"
- DOUBLEFORMAT="LITTLESWAPPED"
-elif strings ./doubleformattest | grep "DCBA3210DCBA3210" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Normal big endian format"
- DOUBLEFORMAT="BIG"
-elif strings ./doubleformattest | grep "3210DCBA3210DCBA" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Swapped big endian format"
- DOUBLEFORMAT="BIGSWAPPED"
-fi
-
-# done
-if [ "$DOUBLEFORMAT" = "LITTLE" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using little endian."
- exit 10
-elif [ "$DOUBLEFORMAT" = "BIG" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using big endian."
- exit 11
-elif [ "$DOUBLEFORMAT" = "LITTLESWAPPED" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using swapped little endian."
- exit 12
-elif [ "$DOUBLEFORMAT" = "BIGSWAPPED" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using swapped big endian."
- exit 13
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown floating point format!"
- exit 99
-fi
diff --git a/config.tests/unix/doubleformat/doubleformattest.pro b/config.tests/unix/doubleformat/doubleformattest.pro
deleted file mode 100644
index 7e51deade5..0000000000
--- a/config.tests/unix/doubleformat/doubleformattest.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = doubleformattest.cpp
-CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/endian.test b/config.tests/unix/endian.test
deleted file mode 100755
index a662011a27..0000000000
--- a/config.tests/unix/endian.test
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-QMKSPEC=$1
-VERBOSE=$2
-SRCDIR=$3
-OUTDIR=$4
-QMFLAGS=$5
-
-# debuggery
-[ "$VERBOSE" = "yes" ] && echo "Determining machine byte-order... ($*)"
-
-# build and run a test program
-test -d "$OUTDIR/config.tests/unix/endian" || mkdir -p "$OUTDIR/config.tests/unix/endian"
-"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" $QMFLAGS "$SRCDIR/config.tests/unix/endian/endiantest.pro" -o "$OUTDIR/config.tests/unix/endian/Makefile" >/dev/null 2>&1
-cd "$OUTDIR/config.tests/unix/endian"
-
-
-ENDIAN="UNKNOWN"
-[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1
-
-if [ -f ./endiantest.exe ]; then
- binary=./endiantest.exe
-else
- binary=./endiantest
-fi
-
-
-if [ -f $binary ]; then
- : # nop
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown byte order!"
- exit 2
-fi
-
-if strings - $binary | grep LeastSignificantByteFirst >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Found 'LeastSignificantByteFirst' in binary"
- ENDIAN="LITTLE"
-elif strings - $binary | grep MostSignificantByteFirst >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Found 'MostSignificantByteFirst' in binary"
- ENDIAN="BIG"
-fi
-
-# make clean as this tests is compiled for both the host and the target
-if [ "$VERBOSE" = "yes" ]; then
- $MAKE distclean
-else
- $MAKE distclean >/dev/null 2>&1
-fi
-
-# done
-if [ "$ENDIAN" = "LITTLE" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using little endian."
- exit 0
-elif [ "$ENDIAN" = "BIG" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using big endian."
- exit 1
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown byte order!"
- exit 2
-fi
diff --git a/config.tests/unix/endian/endiantest.pro b/config.tests/unix/endian/endiantest.pro
deleted file mode 100644
index 7b739eb3f2..0000000000
--- a/config.tests/unix/endian/endiantest.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = endiantest.cpp
-CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/configure b/configure
index de65cdc7bc..90e0a5fcda 100755
--- a/configure
+++ b/configure
@@ -359,7 +359,6 @@ earlyArgParse()
if [ "$PLATFORM_QPA" != "no" ]; then
if [ "$PLATFORM_QPA" = "maybe" ]; then
PLATFORM_X11=no
- PLATFORM_MAC=no
PLATFORM_QPA=yes
fi
else
@@ -764,10 +763,6 @@ CFG_AVX=auto
CFG_REDUCE_RELOCATIONS=auto
CFG_NAS=no
CFG_ACCESSIBILITY=auto
-CFG_ENDIAN=auto
-CFG_HOST_ENDIAN=auto
-CFG_DOUBLEFORMAT=auto
-CFG_ARMFPA=auto
CFG_IWMMXT=no
CFG_NEON=auto
CFG_CLOCK_GETTIME=auto
@@ -965,7 +960,7 @@ while [ "$#" -gt 0 ]; do
VAL=no
;;
#Qt style yes options
- -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-wayland|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-declarative-debug|-javascript-jit|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon)
+ -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-wayland|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-declarative-debug|-javascript-jit|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon)
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
VAL=yes
;;
@@ -1041,14 +1036,6 @@ while [ "$#" -gt 0 ]; do
VAL=$1
fi
;;
- -host-*-endian)
- VAR=host_endian
- VAL=`echo $1 | sed "s,^-.*-\(.*\)-.*,\1,"`
- ;;
- -*-endian)
- VAR=endian
- VAL=`echo $1 | sed "s,^-\(.*\)-.*,\1,"`
- ;;
-qtnamespace)
VAR="qtnamespace"
shift
@@ -1231,7 +1218,6 @@ while [ "$#" -gt 0 ]; do
;;
embedded-lite|qpa)
PLATFORM_X11=no
- PLATFORM_MAC=no
PLATFORM_QPA=yes
;;
sse)
@@ -1241,31 +1227,6 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
- endian)
- if [ "$VAL" = "little" ]; then
- CFG_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$VAL" = "big" ]; then
- CFG_ENDIAN="Q_BIG_ENDIAN"
- else
- UNKNOWN_OPT=yes
- fi
- ;;
- host_endian)
- if [ "$VAL" = "little" ]; then
- CFG_HOST_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$VAL" = "big" ]; then
- CFG_HOST_ENDIAN="Q_BIG_ENDIAN"
- else
- UNKNOWN_OPT=yes
- fi
- ;;
- armfpa)
- if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
- CFG_ARMFPA="$VAL"
- else
- UNKNOWN_OPT=yes
- fi
- ;;
opengl)
if [ "$VAL" = "auto" ] || [ "$VAL" = "desktop" ] ||
[ "$VAL" = "yes" ] || [ "$VAL" = "no" ] ||
@@ -3249,7 +3210,7 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir
[-iconv] [-no-pch] [-pch] [-no-dbus] [-dbus] [-dbus-linked] [-no-gui]
[-no-separate-debug-info] [-no-mmx] [-no-3dnow] [-no-sse] [-no-sse2]
[-no-sse3] [-no-ssse3] [-no-sse4.1] [-no-sse4.2] [-no-avx] [-no-neon]
- [-qtnamespace <namespace>] [-qtlibinfix <infix>] [-separate-debug-info] [-armfpa]
+ [-qtnamespace <namespace>] [-qtlibinfix <infix>] [-separate-debug-info]
[-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend]
[-no-audio-backend] [-audio-backend]
[-no-javascript-jit] [-javascript-jit] [-no-declarative-debug] [-declarative-debug]
@@ -3793,22 +3754,6 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
-feature-<feature> .. Compile in <feature>. The available features
are described in src/corelib/global/qfeatures.txt
- -armfpa ............. Target platform uses the ARM-FPA floating point format.
- -no-armfpa .......... Target platform does not use the ARM-FPA floating point format.
-
- The floating point format is usually autodetected by configure. Use this
- to override the detected value.
-
- -little-endian ...... Target platform is little endian (LSB first).
- -big-endian ......... Target platform is big endian (MSB first).
-
- -host-little-endian . Host platform is little endian (LSB first).
- -host-big-endian .... Host platform is big endian (MSB first).
-
- You only need to specify the endianness when
- cross-compiling, otherwise the host
- endianness will be used.
-
-no-freetype ........ Do not compile in Freetype2 support.
-qt-freetype ........ Use the libfreetype bundled with Qt.
* -system-freetype .... Use libfreetype from the operating system.
@@ -5493,6 +5438,8 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
echo " If you really want to build without a QPA platform plugin you must pass"
echo " -no-xcb and -no-wayland to configure. Doing this will produce a Qt that"
echo " cannot run GUI applications."
+ echo " The dependencies needed for xcb to build are listed in"
+ echo " src/plugins/platforms/xcb/README"
exit 1
fi
fi
@@ -5541,93 +5488,6 @@ if [ "$CFG_LIBFREETYPE" = "auto" ]; then
fi
fi
-if [ "$CFG_ENDIAN" = "auto" ]; then
- if [ "$XPLATFORM_MINGW" = "yes" ]; then
- CFG_ENDIAN="Q_LITTLE_ENDIAN"
- else
- "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "QMAKE_LFLAGS+=$SYSROOT_FLAG"
- F="$?"
- if [ "$F" -eq 0 ]; then
- CFG_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$F" -eq 1 ]; then
- CFG_ENDIAN="Q_BIG_ENDIAN"
- else
- echo
- echo "The target system byte order could not be detected!"
- echo "Turn on verbose messaging (-v) to see the final report."
- echo "You can use the -little-endian or -big-endian switch to"
- echo "$0 to continue."
- exit 101
- fi
- fi
-fi
-
-if [ "$CFG_HOST_ENDIAN" = "auto" ]; then
- if [ "$BUILD_ON_MAC" = "yes" ]; then
- true #leave as auto
- else
- "$unixtests/endian.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath"
- F="$?"
- if [ "$F" -eq 0 ]; then
- CFG_HOST_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$F" -eq 1 ]; then
- CFG_HOST_ENDIAN="Q_BIG_ENDIAN"
- else
- echo
- echo "The host system byte order could not be detected!"
- echo "Turn on verbose messaging (-v) to see the final report."
- echo "You can use the -host-little-endian or -host-big-endian switch to"
- echo "$0 to continue."
- exit 101
- fi
- fi
-fi
-
-if [ "$CFG_ARMFPA" != "auto" ]; then
- if [ "$CFG_ARMFPA" = "yes" ]; then
- if [ "$CFG_ENDIAN" = "Q_LITTLE_ENDIAN" ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE_SWAPPED"
- else
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG_SWAPPED"
- fi
- else
- CFG_DOUBLEFORMAT="normal"
- fi
-fi
-
-
-if [ "$CFG_DOUBLEFORMAT" = "auto" ]; then
- if [ "$PLATFORM_QPA" = "yes" ]; then
- CFG_DOUBLEFORMAT=normal
- else
- "$unixtests/doubleformat.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath"
- F="$?"
- if [ "$F" -eq 10 ] && [ "$CFG_ENDIAN" = "Q_LITTLE_ENDIAN" ]; then
- CFG_DOUBLEFORMAT=normal
- elif [ "$F" -eq 11 ] && [ "$CFG_ENDIAN" = "Q_BIG_ENDIAN" ]; then
- CFG_DOUBLEFORMAT=normal
- elif [ "$F" -eq 10 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE"
- elif [ "$F" -eq 11 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG"
- elif [ "$F" -eq 12 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE_SWAPPED"
- CFG_ARMFPA="yes"
- elif [ "$F" -eq 13 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG_SWAPPED"
- CFG_ARMFPA="yes"
- else
- echo
- echo "The system floating point format could not be detected."
- echo "This may cause data to be generated in a wrong format"
- echo "Turn on verbose messaging (-v) to see the final report."
- # we do not fail on this since this is a new test, and if it fails,
- # the old behavior should be correct in most cases
- CFG_DOUBLEFORMAT=normal
- fi
- fi
-fi
-
HAVE_STL=no
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then
HAVE_STL=yes
@@ -6501,63 +6361,7 @@ cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
#ifndef QT_EDITION
# define QT_EDITION $QT_EDITION
#endif
-
-/* Machine byte-order */
-#define Q_BIG_ENDIAN 4321
-#define Q_LITTLE_ENDIAN 1234
-EOF
-
-echo "#ifdef QT_BOOTSTRAPPED" >>"$outpath/src/corelib/global/qconfig.h.new"
-if [ "$CFG_HOST_ENDIAN" = "auto" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
-#if defined(__BIG_ENDIAN__)
-# define Q_BYTE_ORDER Q_BIG_ENDIAN
-#elif defined(__LITTLE_ENDIAN__)
-# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
-#else
-# error "Unable to determine byte order!"
-#endif
-EOF
-else
- echo "#define Q_BYTE_ORDER $CFG_HOST_ENDIAN" >>"$outpath/src/corelib/global/qconfig.h.new"
-fi
-echo "#else" >>"$outpath/src/corelib/global/qconfig.h.new"
-if [ "$CFG_ENDIAN" = "auto" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
-#if defined(__BIG_ENDIAN__)
-# define Q_BYTE_ORDER Q_BIG_ENDIAN
-#elif defined(__LITTLE_ENDIAN__)
-# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
-#else
-# error "Unable to determine byte order!"
-#endif
EOF
-else
- echo "#define Q_BYTE_ORDER $CFG_ENDIAN" >>"$outpath/src/corelib/global/qconfig.h.new"
-fi
-echo "#endif" >>"$outpath/src/corelib/global/qconfig.h.new"
-
-if [ "$CFG_DOUBLEFORMAT" != "normal" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
-/* Non-IEEE double format */
-#define Q_DOUBLE_LITTLE "01234567"
-#define Q_DOUBLE_BIG "76543210"
-#define Q_DOUBLE_LITTLE_SWAPPED "45670123"
-#define Q_DOUBLE_BIG_SWAPPED "32107654"
-#define Q_DOUBLE_FORMAT $CFG_DOUBLEFORMAT
-EOF
-fi
-if [ "$CFG_ARMFPA" = "yes" ]; then
- if [ "$CFG_ARCH" != "$CFG_HOST_ARCH" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
-#ifndef QT_BOOTSTRAPPED
-# define QT_ARMFPA
-#endif
-EOF
- else
- echo "#define QT_ARMFPA" >>"$outpath/src/corelib/global/qconfig.h.new"
- fi
-fi
CFG_ARCH_STR=`echo $CFG_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
CFG_HOST_ARCH_STR=`echo $CFG_HOST_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
diff --git a/configure.bat b/configure.bat
index e872de2797..b5ffb14731 100644
--- a/configure.bat
+++ b/configure.bat
@@ -67,9 +67,7 @@ if not exist src\corelib\global\qconfig.h (
md src\corelib\global
if errorlevel 1 goto exit
)
- echo #define Q_BIG_ENDIAN 4321 > src\corelib\global\qconfig.h
- echo #define Q_LITTLE_ENDIAN 1234 >> src\corelib\global\qconfig.h
- echo #define Q_BYTE_ORDER Q_LITTLE_ENDIAN >> src\corelib\global\qconfig.h
+ echo /* Generated by configure.bat - DO NOT EDIT! */ > src\corelib\global\qconfig.h
)
if not exist tools\configure (
@@ -117,5 +115,5 @@ if errorlevel 1 (cd ..\.. & exit /b 1)
cd ..\..
:conf
-configure.exe -srcdir %QTSRC% %nosyncqt% %*
+configure.exe -srcdir %QTSRC% %* %nosyncqt%
:exit
diff --git a/dist/README b/dist/README
index 815e12be9e..1206280265 100644
--- a/dist/README
+++ b/dist/README
@@ -74,7 +74,7 @@ HOW TO REPORT A BUG
If you think you have found a bug in Qt, we would like to hear about
it so that we can fix it. The Qt bug tracking system is open to the
-public at http://bugreports.qt.nokia.com/.
+public at http://bugreports.qt-project.org/.
Before reporting a bug, please use the bug-tracker's search functions
and consult http://qt.nokia.com/developer/faqs/ to see if the issue is
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index ca9047b682..47994aa774 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -1,7 +1,7 @@
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
- http://bugreports.qt.nokia.com/
+ http://bugreports.qt-project.org/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
@@ -202,6 +202,7 @@ information about a particular change.
- qmake
* Projects which explicitly set an empty TARGET are considered broken now.
+ * The makespec and .qmake.cache do not see build pass specific variables any more.
* Configure's -sysroot and -hostprefix are now handled slightly differently.
The QT_INSTALL_... properties are now automatically prefixed with the sysroot;
the raw values are available as QT_RAW_INSTALL_... and the sysroot as QT_SYSROOT.
diff --git a/doc/src/corelib/containers.qdoc b/doc/src/corelib/containers.qdoc
index e28c3bdbfe..b63cc9df28 100644
--- a/doc/src/corelib/containers.qdoc
+++ b/doc/src/corelib/containers.qdoc
@@ -104,10 +104,10 @@
efficient hash-lookup of objects in a limited cache storage.
\table
- \header \o Class \o Summary
+ \header \li Class \li Summary
- \row \o \l{QList}<T>
- \o This is by far the most commonly used container class. It
+ \row \li \l{QList}<T>
+ \li This is by far the most commonly used container class. It
stores a list of values of a given type (T) that can be accessed
by index. Internally, the QList is implemented using an array,
ensuring that index-based access is very fast.
@@ -119,8 +119,8 @@
possible in the executable. QStringList inherits from
QList<QString>.
- \row \o \l{QLinkedList}<T>
- \o This is similar to QList, except that it uses
+ \row \li \l{QLinkedList}<T>
+ \li This is similar to QList, except that it uses
iterators rather than integer indexes to access items. It also
provides better performance than QList when inserting in the
middle of a huge list, and it has nicer iterator semantics.
@@ -128,48 +128,48 @@
long as the item exists, whereas iterators to a QList can become
invalid after any insertion or removal.)
- \row \o \l{QVector}<T>
- \o This stores an array of values of a given type at adjacent
+ \row \li \l{QVector}<T>
+ \li This stores an array of values of a given type at adjacent
positions in memory. Inserting at the front or in the middle of
a vector can be quite slow, because it can lead to large numbers
of items having to be moved by one position in memory.
- \row \o \l{QStack}<T>
- \o This is a convenience subclass of QVector that provides
+ \row \li \l{QStack}<T>
+ \li This is a convenience subclass of QVector that provides
"last in, first out" (LIFO) semantics. It adds the following
functions to those already present in QVector:
\l{QStack::push()}{push()}, \l{QStack::pop()}{pop()},
and \l{QStack::top()}{top()}.
- \row \o \l{QQueue}<T>
- \o This is a convenience subclass of QList that provides
+ \row \li \l{QQueue}<T>
+ \li This is a convenience subclass of QList that provides
"first in, first out" (FIFO) semantics. It adds the following
functions to those already present in QList:
\l{QQueue::enqueue()}{enqueue()},
\l{QQueue::dequeue()}{dequeue()}, and \l{QQueue::head()}{head()}.
- \row \o \l{QSet}<T>
- \o This provides a single-valued mathematical set with fast
+ \row \li \l{QSet}<T>
+ \li This provides a single-valued mathematical set with fast
lookups.
- \row \o \l{QMap}<Key, T>
- \o This provides a dictionary (associative array) that maps keys
+ \row \li \l{QMap}<Key, T>
+ \li This provides a dictionary (associative array) that maps keys
of type Key to values of type T. Normally each key is associated
with a single value. QMap stores its data in Key order; if order
doesn't matter QHash is a faster alternative.
- \row \o \l{QMultiMap}<Key, T>
- \o This is a convenience subclass of QMap that provides a nice
+ \row \li \l{QMultiMap}<Key, T>
+ \li This is a convenience subclass of QMap that provides a nice
interface for multi-valued maps, i.e. maps where one key can be
associated with multiple values.
- \row \o \l{QHash}<Key, T>
- \o This has almost the same API as QMap, but provides
+ \row \li \l{QHash}<Key, T>
+ \li This has almost the same API as QMap, but provides
significantly faster lookups. QHash stores its data in an
arbitrary order.
- \row \o \l{QMultiHash}<Key, T>
- \o This is a convenience subclass of QHash that
+ \row \li \l{QMultiHash}<Key, T>
+ \li This is a convenience subclass of QHash that
provides a nice interface for multi-valued hashes.
\endtable
@@ -271,20 +271,20 @@
read-write access.
\table
- \header \o Containers \o Read-only iterator
- \o Read-write iterator
- \row \o QList<T>, QQueue<T> \o QListIterator<T>
- \o QMutableListIterator<T>
- \row \o QLinkedList<T> \o QLinkedListIterator<T>
- \o QMutableLinkedListIterator<T>
- \row \o QVector<T>, QStack<T> \o QVectorIterator<T>
- \o QMutableVectorIterator<T>
- \row \o QSet<T> \o QSetIterator<T>
- \o QMutableSetIterator<T>
- \row \o QMap<Key, T>, QMultiMap<Key, T> \o QMapIterator<Key, T>
- \o QMutableMapIterator<Key, T>
- \row \o QHash<Key, T>, QMultiHash<Key, T> \o QHashIterator<Key, T>
- \o QMutableHashIterator<Key, T>
+ \header \li Containers \li Read-only iterator
+ \li Read-write iterator
+ \row \li QList<T>, QQueue<T> \li QListIterator<T>
+ \li QMutableListIterator<T>
+ \row \li QLinkedList<T> \li QLinkedListIterator<T>
+ \li QMutableLinkedListIterator<T>
+ \row \li QVector<T>, QStack<T> \li QVectorIterator<T>
+ \li QMutableVectorIterator<T>
+ \row \li QSet<T> \li QSetIterator<T>
+ \li QMutableSetIterator<T>
+ \row \li QMap<Key, T>, QMultiMap<Key, T> \li QMapIterator<Key, T>
+ \li QMutableMapIterator<Key, T>
+ \row \li QHash<Key, T>, QMultiHash<Key, T> \li QHashIterator<Key, T>
+ \li QMutableHashIterator<Key, T>
\endtable
In this discussion, we will concentrate on QList and QMap. The
@@ -334,23 +334,23 @@
The following table summarizes the QListIterator API:
\table
- \header \o Function \o Behavior
- \row \o \l{QListIterator::toFront()}{toFront()}
- \o Moves the iterator to the front of the list (before the first item)
- \row \o \l{QListIterator::toBack()}{toBack()}
- \o Moves the iterator to the back of the list (after the last item)
- \row \o \l{QListIterator::hasNext()}{hasNext()}
- \o Returns true if the iterator isn't at the back of the list
- \row \o \l{QListIterator::next()}{next()}
- \o Returns the next item and advances the iterator by one position
- \row \o \l{QListIterator::peekNext()}{peekNext()}
- \o Returns the next item without moving the iterator
- \row \o \l{QListIterator::hasPrevious()}{hasPrevious()}
- \o Returns true if the iterator isn't at the front of the list
- \row \o \l{QListIterator::previous()}{previous()}
- \o Returns the previous item and moves the iterator back by one position
- \row \o \l{QListIterator::peekPrevious()}{peekPrevious()}
- \o Returns the previous item without moving the iterator
+ \header \li Function \li Behavior
+ \row \li \l{QListIterator::toFront()}{toFront()}
+ \li Moves the iterator to the front of the list (before the first item)
+ \row \li \l{QListIterator::toBack()}{toBack()}
+ \li Moves the iterator to the back of the list (after the last item)
+ \row \li \l{QListIterator::hasNext()}{hasNext()}
+ \li Returns true if the iterator isn't at the back of the list
+ \row \li \l{QListIterator::next()}{next()}
+ \li Returns the next item and advances the iterator by one position
+ \row \li \l{QListIterator::peekNext()}{peekNext()}
+ \li Returns the next item without moving the iterator
+ \row \li \l{QListIterator::hasPrevious()}{hasPrevious()}
+ \li Returns true if the iterator isn't at the front of the list
+ \row \li \l{QListIterator::previous()}{previous()}
+ \li Returns the previous item and moves the iterator back by one position
+ \row \li \l{QListIterator::peekPrevious()}{peekPrevious()}
+ \li Returns the previous item without moving the iterator
\endtable
QListIterator provides no functions to insert or remove items
@@ -440,20 +440,20 @@
possible because they are faster than read-write iterators.
\table
- \header \o Containers \o Read-only iterator
- \o Read-write iterator
- \row \o QList<T>, QQueue<T> \o QList<T>::const_iterator
- \o QList<T>::iterator
- \row \o QLinkedList<T> \o QLinkedList<T>::const_iterator
- \o QLinkedList<T>::iterator
- \row \o QVector<T>, QStack<T> \o QVector<T>::const_iterator
- \o QVector<T>::iterator
- \row \o QSet<T> \o QSet<T>::const_iterator
- \o QSet<T>::iterator
- \row \o QMap<Key, T>, QMultiMap<Key, T> \o QMap<Key, T>::const_iterator
- \o QMap<Key, T>::iterator
- \row \o QHash<Key, T>, QMultiHash<Key, T> \o QHash<Key, T>::const_iterator
- \o QHash<Key, T>::iterator
+ \header \li Containers \li Read-only iterator
+ \li Read-write iterator
+ \row \li QList<T>, QQueue<T> \li QList<T>::const_iterator
+ \li QList<T>::iterator
+ \row \li QLinkedList<T> \li QLinkedList<T>::const_iterator
+ \li QLinkedList<T>::iterator
+ \row \li QVector<T>, QStack<T> \li QVector<T>::const_iterator
+ \li QVector<T>::iterator
+ \row \li QSet<T> \li QSet<T>::const_iterator
+ \li QSet<T>::iterator
+ \row \li QMap<Key, T>, QMultiMap<Key, T> \li QMap<Key, T>::const_iterator
+ \li QMap<Key, T>::iterator
+ \row \li QHash<Key, T>, QMultiHash<Key, T> \li QHash<Key, T>::const_iterator
+ \li QHash<Key, T>::iterator
\endtable
The API of the STL iterators is modelled on pointers in an array.
@@ -509,13 +509,13 @@
The following table summarizes the STL-style iterators' API:
\table
- \header \o Expression \o Behavior
- \row \o \c{*i} \o Returns the current item
- \row \o \c{++i} \o Advances the iterator to the next item
- \row \o \c{i += n} \o Advances the iterator by \c n items
- \row \o \c{--i} \o Moves the iterator back by one item
- \row \o \c{i -= n} \o Moves the iterator back by \c n items
- \row \o \c{i - j} \o Returns the number of items between iterators \c i and \c j
+ \header \li Expression \li Behavior
+ \row \li \c{*i} \li Returns the current item
+ \row \li \c{++i} \li Advances the iterator to the next item
+ \row \li \c{i += n} \li Advances the iterator by \c n items
+ \row \li \c{--i} \li Moves the iterator back by one item
+ \row \li \c{i -= n} \li Moves the iterator back by \c n items
+ \row \li \c{i - j} \li Returns the number of items between iterators \c i and \c j
\endtable
The \c{++} and \c{--} operators are available both as prefix
@@ -625,17 +625,17 @@
be used with the \c foreach keyword.
\list
- \o QVarLengthArray<T, Prealloc> provides a low-level
+ \li QVarLengthArray<T, Prealloc> provides a low-level
variable-length array. It can be used instead of QVector in
places where speed is particularly important.
- \o QCache<Key, T> provides a cache to store objects of a certain
+ \li QCache<Key, T> provides a cache to store objects of a certain
type T associated with keys of type Key.
- \o QContiguousCache<T> provides an efficient way of caching data
+ \li QContiguousCache<T> provides an efficient way of caching data
that is typically accessed in a contiguous way.
- \o QPair<T1, T2> stores a pair of elements.
+ \li QPair<T1, T2> stores a pair of elements.
\endlist
Additional non-template types that compete with Qt's template
@@ -662,27 +662,27 @@
\keyword quadratic time
\list
- \o \bold{Constant time:} O(1). A function is said to run in constant
+ \li \b{Constant time:} O(1). A function is said to run in constant
time if it requires the same amount of time no matter how many
items are present in the container. One example is
QLinkedList::insert().
- \o \bold{Logarithmic time:} O(log \e n). A function that runs in
+ \li \b{Logarithmic time:} O(log \e n). A function that runs in
logarithmic time is a function whose running time is
proportional to the logarithm of the number of items in the
container. One example is qBinaryFind().
- \o \bold{Linear time:} O(\e n). A function that runs in linear time
+ \li \b{Linear time:} O(\e n). A function that runs in linear time
will execute in a time directly proportional to the number of
items stored in the container. One example is
QVector::insert().
- \o \bold{Linear-logarithmic time:} O(\e{n} log \e n). A function
+ \li \b{Linear-logarithmic time:} O(\e{n} log \e n). A function
that runs in linear-logarithmic time is asymptotically slower
than a linear-time function, but faster than a quadratic-time
function.
- \o \bold{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function
+ \li \b{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function
executes in a time that is proportional to the square of the
number of items stored in the container.
\endlist
@@ -691,10 +691,10 @@
sequential container classes:
\table
- \header \o \o Index lookup \o Insertion \o Prepending \o Appending
- \row \o QLinkedList<T> \o O(\e n) \o O(1) \o O(1) \o O(1)
- \row \o QList<T> \o O(1) \o O(n) \o Amort. O(1) \o Amort. O(1)
- \row \o QVector<T> \o O(1) \o O(n) \o O(n) \o Amort. O(1)
+ \header \li \li Index lookup \li Insertion \li Prepending \li Appending
+ \row \li QLinkedList<T> \li O(\e n) \li O(1) \li O(1) \li O(1)
+ \row \li QList<T> \li O(1) \li O(n) \li Amort. O(1) \li Amort. O(1)
+ \row \li QVector<T> \li O(1) \li O(n) \li O(n) \li Amort. O(1)
\endtable
In the table, "Amort." stands for "amortized behavior". For
@@ -707,12 +707,12 @@
associative containers and sets:
\table
- \header \o{1,2} \o{2,1} Key lookup \o{2,1} Insertion
- \header \o Average \o Worst case \o Average \o Worst case
- \row \o QMap<Key, T> \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n)
- \row \o QMultiMap<Key, T> \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n)
- \row \o QHash<Key, T> \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n)
- \row \o QSet<Key> \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n)
+ \header \li{1,2} \li{2,1} Key lookup \li{2,1} Insertion
+ \header \li Average \li Worst case \li Average \li Worst case
+ \row \li QMap<Key, T> \li O(log \e n) \li O(log \e n) \li O(log \e n) \li O(log \e n)
+ \row \li QMultiMap<Key, T> \li O(log \e n) \li O(log \e n) \li O(log \e n) \li O(log \e n)
+ \row \li QHash<Key, T> \li Amort. O(1) \li O(\e n) \li Amort. O(1) \li O(\e n)
+ \row \li QSet<Key> \li Amort. O(1) \li O(\e n) \li Amort. O(1) \li O(\e n)
\endtable
With QVector, QHash, and QSet, the performance of appending items
@@ -749,13 +749,13 @@
The values above may seem a bit strange, but here are the guiding
principles:
\list
- \o QString allocates 4 characters at a time until it reaches size 20.
- \o From 20 to 4084, it advances by doubling the size each time.
+ \li QString allocates 4 characters at a time until it reaches size 20.
+ \li From 20 to 4084, it advances by doubling the size each time.
More precisely, it advances to the next power of two, minus
12. (Some memory allocators perform worst when requested exact
powers of two, because they use a few bytes per block for
book-keeping.)
- \o From 4084 on, it advances by blocks of 2048 characters (4096
+ \li From 4084 on, it advances by blocks of 2048 characters (4096
bytes). This makes sense because modern operating systems
don't copy the entire data when reallocating a buffer; the
physical memory pages are simply reordered, and only the data
@@ -787,12 +787,12 @@
use to store the items:
\list
- \o \l{QString::capacity()}{capacity()} returns the
+ \li \l{QString::capacity()}{capacity()} returns the
number of items for which memory is allocated (for QHash and
QSet, the number of buckets in the hash table).
- \o \l{QString::reserve()}{reserve}(\e size) explicitly
+ \li \l{QString::reserve()}{reserve}(\e size) explicitly
preallocates memory for \e size items.
- \o \l{QString::squeeze()}{squeeze()} frees any memory
+ \li \l{QString::squeeze()}{squeeze()} frees any memory
not required to store the items.
\endlist
diff --git a/doc/src/corelib/json.qdoc b/doc/src/corelib/json.qdoc
index 91a89761e3..88b5377074 100644
--- a/doc/src/corelib/json.qdoc
+++ b/doc/src/corelib/json.qdoc
@@ -59,12 +59,12 @@
JSON is a format to store structured data. It has 6 basic data types:
\list
- \o bool
- \o double
- \o string
- \o array
- \o object
- \o null
+ \li bool
+ \li double
+ \li string
+ \li array
+ \li object
+ \li null
\endlist
Any value can be any of the above type. A boolean value is represented by the
diff --git a/doc/src/corelib/objectmodel/metaobjects.qdoc b/doc/src/corelib/objectmodel/metaobjects.qdoc
index 7edb376e25..c92f6f2f09 100644
--- a/doc/src/corelib/objectmodel/metaobjects.qdoc
+++ b/doc/src/corelib/objectmodel/metaobjects.qdoc
@@ -41,12 +41,12 @@
The meta-object system is based on three things:
\list 1
- \o The \l QObject class provides a base class for objects that can
+ \li The \l QObject class provides a base class for objects that can
take advantage of the meta-object system.
- \o The Q_OBJECT macro inside the private section of the class
+ \li The Q_OBJECT macro inside the private section of the class
declaration is used to enable meta-object features, such as
dynamic properties, signals, and slots.
- \o The \l{moc}{Meta-Object Compiler} (\c moc) supplies each
+ \li The \l{moc}{Meta-Object Compiler} (\c moc) supplies each
QObject subclass with the necessary code to implement
meta-object features.
\endlist
@@ -64,19 +64,19 @@
additional features:
\list
- \o QObject::metaObject() returns the associated
+ \li QObject::metaObject() returns the associated
\l{QMetaObject}{meta-object} for the class.
- \o QMetaObject::className() returns the class name as a
+ \li QMetaObject::className() returns the class name as a
string at run-time, without requiring native run-time type information
(RTTI) support through the C++ compiler.
- \o QObject::inherits() function returns whether an object is an
+ \li QObject::inherits() function returns whether an object is an
instance of a class that inherits a specified class within the
QObject inheritance tree.
- \o QObject::tr() and QObject::trUtf8() translate strings for
+ \li QObject::tr() and QObject::trUtf8() translate strings for
\l{Internationalization with Qt}{internationalization}.
- \o QObject::setProperty() and QObject::property()
+ \li QObject::setProperty() and QObject::property()
dynamically set and get properties by name.
- \o QMetaObject::newInstance() constructs a new instance of the class.
+ \li QMetaObject::newInstance() constructs a new instance of the class.
\endlist
\target qobjectcast
diff --git a/doc/src/corelib/objectmodel/object.qdoc b/doc/src/corelib/objectmodel/object.qdoc
index cf3ce4ef31..4e212b37dd 100644
--- a/doc/src/corelib/objectmodel/object.qdoc
+++ b/doc/src/corelib/objectmodel/object.qdoc
@@ -41,20 +41,20 @@
Qt adds these features to C++:
\list
- \o a very powerful mechanism for seamless object
+ \li a very powerful mechanism for seamless object
communication called \l{signals and slots}
- \o queryable and designable \l{Qt's Property System}{object
+ \li queryable and designable \l{Qt's Property System}{object
properties}
- \o powerful \l{The Event System}{events and event filters}
- \o contextual \l{i18n}{string translation for internationalization}
- \o sophisticated interval driven \l timers that make it possible
+ \li powerful \l{The Event System}{events and event filters}
+ \li contextual \l{i18n}{string translation for internationalization}
+ \li sophisticated interval driven \l timers that make it possible
to elegantly integrate many tasks in an event-driven GUI
- \o hierarchical and queryable \l{Object Trees & Ownership}{object
+ \li hierarchical and queryable \l{Object Trees & Ownership}{object
trees} that organize object ownership in a natural way
- \o guarded pointers (QPointer) that are automatically
+ \li guarded pointers (QPointer) that are automatically
set to 0 when the referenced object is destroyed, unlike normal C++
pointers which become dangling pointers when their objects are destroyed
- \o a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across
+ \li a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across
library boundaries.
\endlist
@@ -92,22 +92,22 @@
or assigning a value. We can see what this means in the Qt Object
Model.
- \bold{A Qt Object...}
+ \b{A Qt Object...}
\list
- \o might have a unique \l{QObject::objectName()}. If we copy a Qt
+ \li might have a unique \l{QObject::objectName()}. If we copy a Qt
Object, what name should we give the copy?
- \o has a location in an \l{Object Trees & Ownership}
+ \li has a location in an \l{Object Trees & Ownership}
{object hierarchy}. If we copy a Qt Object, where should the copy
be located?
- \o can be connected to other Qt Objects to emit signals to them or
+ \li can be connected to other Qt Objects to emit signals to them or
to receive signals emitted by them. If we copy a Qt Object, how
should we transfer these connections to the copy?
- \o can have \l{Qt's Property System} {new properties} added to it
+ \li can have \l{Qt's Property System} {new properties} added to it
at runtime that are not declared in the C++ class. If we copy a Qt
Object, should the copy include the properties that were added to
the original?
diff --git a/doc/src/corelib/objectmodel/properties.qdoc b/doc/src/corelib/objectmodel/properties.qdoc
index 894efd017d..4d090af8fc 100644
--- a/doc/src/corelib/objectmodel/properties.qdoc
+++ b/doc/src/corelib/objectmodel/properties.qdoc
@@ -58,20 +58,20 @@
\list
- \o A \c READ accessor function is required. It is for reading the
+ \li A \c READ accessor function is required. It is for reading the
property value. Ideally, a const function is used for this purpose,
and it must return either the property's type or a pointer or
reference to that type. e.g., QWidget::focus is a read-only property
with \c READ function, QWidget::hasFocus().
- \o A \c WRITE accessor function is optional. It is for setting the
+ \li A \c WRITE accessor function is optional. It is for setting the
property value. It must return void and must take exactly one
argument, either of the property's type or a pointer or reference
to that type. e.g., QWidget::enabled has the \c WRITE function
QWidget::setEnabled(). Read-only properties do not need \c WRITE
functions. e.g., QWidget::focus has no \c WRITE function.
- \o A \c RESET function is optional. It is for setting the property
+ \li A \c RESET function is optional. It is for setting the property
back to its context specific default value. e.g., QWidget::cursor
has the typical \c READ and \c WRITE functions, QWidget::cursor()
and QWidget::setCursor(), and it also has a \c RESET function,
@@ -79,26 +79,26 @@
mean \e {reset to the context specific cursor}. The \c RESET
function must return void and take no parameters.
- \o A \c NOTIFY signal is optional. If defined, it should specify one
+ \li A \c NOTIFY signal is optional. If defined, it should specify one
existing signal in that class that is emitted whenever the value
of the property changes.
- \o A \c REVISION number is optional. If included, it defines the
+ \li A \c REVISION number is optional. If included, it defines the
the property and its notifier signal to be used in a particular
revision of the API that is exposed to QML.
- \o The \c DESIGNABLE attribute indicates whether the property
+ \li The \c DESIGNABLE attribute indicates whether the property
should be visible in the property editor of GUI design tool (e.g.,
\l {Qt Designer}). Most properties are \c DESIGNABLE (default
true). Instead of true or false, you can specify a boolean
member function.
- \o The \c SCRIPTABLE attribute indicates whether this property
+ \li The \c SCRIPTABLE attribute indicates whether this property
should be accessible by a scripting engine (default true).
Instead of true or false, you can specify a boolean member
function.
- \o The \c STORED attribute indicates whether the property should
+ \li The \c STORED attribute indicates whether the property should
be thought of as existing on its own or as depending on other
values. It also indicates whether the property value must be saved
when storing the object's state. Most properties are \c STORED
@@ -106,20 +106,20 @@
false, because its value is just taken from the width component
of property QWidget::minimumSize(), which is a QSize.
- \o The \c USER attribute indicates whether the property is
+ \li The \c USER attribute indicates whether the property is
designated as the user-facing or user-editable property for the
class. Normally, there is only one \c USER property per class
(default false). e.g., QAbstractButton::checked is the user
editable property for (checkable) buttons. Note that QItemDelegate
gets and sets a widget's \c USER property.
- \o The presence of the \c CONSTANT attibute indicates that the property
+ \li The presence of the \c CONSTANT attibute indicates that the property
value is constant. For a given object instance, the READ method of a
constant property must return the same value every time it is called. This
constant value may be different for different instances of the object. A
constant property cannot have a WRITE method or a NOTIFY signal.
- \o The presence of the \c FINAL attribute indicates that the property
+ \li The presence of the \c FINAL attribute indicates that the property
will not be overridden by a derived class. This can be used for performance
optimizations in some cases, but is not enforced by moc. Care must be taken
never to override a \c FINAL property.
diff --git a/doc/src/corelib/threads-basics.qdoc b/doc/src/corelib/threads-basics.qdoc
index 44a3961177..e54f8a7ccb 100644
--- a/doc/src/corelib/threads-basics.qdoc
+++ b/doc/src/corelib/threads-basics.qdoc
@@ -123,8 +123,8 @@
There are basically two use cases for threads:
\list
- \o Make processing faster by making use of multicore processors.
- \o Keep the GUI thread or other time critical threads responsive by
+ \li Make processing faster by making use of multicore processors.
+ \li Keep the GUI thread or other time critical threads responsive by
offloading long lasting processing or blocking calls to other threads.
\endlist
@@ -138,23 +138,23 @@
\table
\header
- \o Alternative
- \o Comment
+ \li Alternative
+ \li Comment
\row
- \o QEventLoop::processEvents()
- \o Calling QEventLoop::processEvents() repeatedly during a
+ \li QEventLoop::processEvents()
+ \li Calling QEventLoop::processEvents() repeatedly during a
time-consuming calculation prevents GUI blocking. However, this
solution doesn't scale well because the call to processEvents() may
occur too often, or not often enough, depending on hardware.
\row
- \o QTimer
- \o Background processing can sometimes be done conveniently using a
+ \li QTimer
+ \li Background processing can sometimes be done conveniently using a
timer to schedule execution of a slot at some point in the future.
A timer with an interval of 0 will time out as soon as there are no
more events to process.
\row
- \o QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
- \o This is an alternative to having one or multiple threads, each with
+ \li QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
+ \li This is an alternative to having one or multiple threads, each with
a blocking read on a slow network connection. As long as the
calculation in response to a chunk of network data can be executed
quickly, this reactive design is better than synchronous waiting in
@@ -183,55 +183,55 @@
\table
\header
- \o Lifetime of thread
- \o Development task
- \o Solution
+ \li Lifetime of thread
+ \li Development task
+ \li Solution
\row
- \o One call
- \o Run one method within another thread and quit the thread when the
+ \li One call
+ \li Run one method within another thread and quit the thread when the
method is finished.
- \o Qt provides different solutions:
+ \li Qt provides different solutions:
\list
- \o Write a function and run it with QtConcurrent::run()
- \o Derive a class from QRunnable and run it in the global thread
+ \li Write a function and run it with QtConcurrent::run()
+ \li Derive a class from QRunnable and run it in the global thread
pool with QThreadPool::globalInstance()->start()
- \o Derive a class from QThread, reimplement the QThread::run()
+ \li Derive a class from QThread, reimplement the QThread::run()
method and use QThread::start() to run it.
\endlist
\row
- \o One call
- \o Operations are to be performed on all items of a container.
+ \li One call
+ \li Operations are to be performed on all items of a container.
Processing should be performed using all available cores. A common
example is to produce thumbnails from a list of images.
- \o QtConcurrent provides the \l{QtConcurrent::}{map()} function for
+ \li QtConcurrent provides the \l{QtConcurrent::}{map()} function for
applying operations on every container element,
\l{QtConcurrent::}{filter()} for selecting container elements, and
the option of specifying a reduce function for combining the
remaining elements.
\row
- \o One call
- \o A long running operation has to be put in another thread. During the
+ \li One call
+ \li A long running operation has to be put in another thread. During the
course of processing, status information should be sent to the GUI
thread.
- \o Use QThread, reimplement run and emit signals as needed. Connect the
+ \li Use QThread, reimplement run and emit signals as needed. Connect the
signals to the GUI thread's slots using queued signal/slot
connections.
\row
- \o Permanent
- \o Have an object living in another thread and let it perform different
+ \li Permanent
+ \li Have an object living in another thread and let it perform different
tasks upon request.
This means communication to and from the worker thread is required.
- \o Derive a class from QObject and implement the necessary slots and
+ \li Derive a class from QObject and implement the necessary slots and
signals, move the object to a thread with a running event loop and
communicate with the object over queued signal/slot connections.
\row
- \o Permanent
- \o Have an object living in another thread, let the object perform
+ \li Permanent
+ \li Have an object living in another thread, let the object perform
repeated tasks such as polling a port and enable communication with
the GUI thread.
- \o Same as above but also use a timer in the worker thread to implement
+ \li Same as above but also use a timer in the worker thread to implement
polling. However, the best solution for polling is to avoid it
completely. Sometimes using QSocketNotifier is an alternative.
\endtable
@@ -304,18 +304,18 @@
The anatomy of QThread is quite interesting:
\list
- \o QThread does not live in the new thread where \l{QThread::}{run()} is
+ \li QThread does not live in the new thread where \l{QThread::}{run()} is
executed. It lives in the old thread.
- \o Most QThread methods are the thread's control interface and are meant to
+ \li Most QThread methods are the thread's control interface and are meant to
be called from the old thread. Do not move this interface to the newly
created thread using \l{QObject::}{moveToThread()}; i.e., calling
\l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad
practice.
- \o \l{QThread::}{exec()} and the static methods
+ \li \l{QThread::}{exec()} and the static methods
\l{QThread::}{usleep()}, \l{QThread::}{msleep()},
\l{QThread::}{sleep()} are meant to be called from the newly created
thread.
- \o Additional members defined in the QThread subclass are
+ \li Additional members defined in the QThread subclass are
accessible by both threads. The developer is responsible for
coordinating access. A typical strategy is to set the members before
\l{QThread::}{start()} is called. Once the worker thread is running,
@@ -432,11 +432,11 @@
main thread.
\list
- \o Using QThread as shown \l{Qt thread basics}{above}
- \o \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
- \o \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
- \o \l{Example 3: Clock}{Communication with the GUI thread}
- \o \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
+ \li Using QThread as shown \l{Qt thread basics}{above}
+ \li \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
+ \li \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
+ \li \l{Example 3: Clock}{Communication with the GUI thread}
+ \li \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
provides service to the main thread}
\endlist
@@ -558,13 +558,13 @@
can help you go into the subject in more depth:
\list
- \o Good video tutorials about threads with Qt can be found in the material
+ \li Good video tutorials about threads with Qt can be found in the material
from the \l{Training Day at Qt Developer Days 2009}.
- \o The \l{Thread Support in Qt} document is a good starting point into
+ \li The \l{Thread Support in Qt} document is a good starting point into
the reference documentation.
- \o Qt comes with several additional examples for
+ \li Qt comes with several additional examples for
\l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}.
- \o Several good books describe how to work with Qt threads. The most
+ \li Several good books describe how to work with Qt threads. The most
extensive coverage can be found in \e{Advanced Qt Programming} by Mark
Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and
QtConcurrent.
diff --git a/doc/src/corelib/threads.qdoc b/doc/src/corelib/threads.qdoc
index 3b4def4174..04a5379b2d 100644
--- a/doc/src/corelib/threads.qdoc
+++ b/doc/src/corelib/threads.qdoc
@@ -54,14 +54,14 @@
\section1 Topics:
\list
- \o \l{Recommended Reading}
- \o \l{The Threading Classes}
- \o \l{Starting Threads with QThread}
- \o \l{Synchronizing Threads}
- \o \l{Reentrancy and Thread-Safety}
- \o \l{Threads and QObjects}
- \o \l{Concurrent Programming}
- \o \l{Thread-Support in Qt Modules}
+ \li \l{Recommended Reading}
+ \li \l{The Threading Classes}
+ \li \l{Starting Threads with QThread}
+ \li \l{Synchronizing Threads}
+ \li \l{Reentrancy and Thread-Safety}
+ \li \l{Threads and QObjects}
+ \li \l{Concurrent Programming}
+ \li \l{Thread-Support in Qt Modules}
\endlist
\section1 Recommended Reading
@@ -71,10 +71,10 @@
to threading see our Recommended Reading list:
\list
- \o \l{Threads Primer: A Guide to Multithreaded Programming}
- \o \l{Thread Time: The Multithreaded Programming Guide}
- \o \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
- \o \l{Win32 Multithreaded Programming}
+ \li \l{Threads Primer: A Guide to Multithreaded Programming}
+ \li \l{Thread Time: The Multithreaded Programming Guide}
+ \li \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
+ \li \l{Win32 Multithreaded Programming}
\endlist
\section1 The Threading Classes
@@ -85,21 +85,21 @@
\omit
\list
- \o QThread provides the means to start a new thread.
- \o QThreadStorage provides per-thread data storage.
- \o QThreadPool manages a pool of threads that run QRunnable objects.
- \o QRunnable is an abstract class representing a runnable object.
- \o QMutex provides a mutual exclusion lock, or mutex.
- \o QMutexLocker is a convenience class that automatically locks
+ \li QThread provides the means to start a new thread.
+ \li QThreadStorage provides per-thread data storage.
+ \li QThreadPool manages a pool of threads that run QRunnable objects.
+ \li QRunnable is an abstract class representing a runnable object.
+ \li QMutex provides a mutual exclusion lock, or mutex.
+ \li QMutexLocker is a convenience class that automatically locks
and unlocks a QMutex.
- \o QReadWriteLock provides a lock that allows simultaneous read access.
- \o QReadLocker and QWriteLocker are convenience classes that automatically
+ \li QReadWriteLock provides a lock that allows simultaneous read access.
+ \li QReadLocker and QWriteLocker are convenience classes that automatically
lock and unlock a QReadWriteLock.
- \o QSemaphore provides an integer semaphore (a generalization of a mutex).
- \o QWaitCondition provides a way for threads to go to sleep until
+ \li QSemaphore provides an integer semaphore (a generalization of a mutex).
+ \li QWaitCondition provides a way for threads to go to sleep until
woken up by another thread.
- \o QAtomicInt provides atomic operations on integers.
- \o QAtomicPointer provides atomic operations on pointers.
+ \li QAtomicInt provides atomic operations on integers.
+ \li QAtomicPointer provides atomic operations on pointers.
\endlist
\endomit
@@ -226,10 +226,10 @@
how they can be used in multithread applications:
\list
- \o A \e thread-safe function can be called simultaneously from
+ \li A \e thread-safe function can be called simultaneously from
multiple threads, even when the invocations use shared data,
because all references to the shared data are serialized.
- \o A \e reentrant function can also be called simultaneously from
+ \li A \e reentrant function can also be called simultaneously from
multiple threads, but only if each invocation uses its own data.
\endlist
@@ -267,9 +267,9 @@
Indeed, they usually expand to three machine instructions:
\list 1
- \o Load the variable's value in a register.
- \o Increment or decrement the register's value.
- \o Store the register's value back into main memory.
+ \li Load the variable's value in a register.
+ \li Increment or decrement the register's value.
+ \li Store the register's value back into main memory.
\endlist
If thread A and thread B load the variable's old value
@@ -346,19 +346,19 @@
guaranteed to work. There are three constraints to be aware of:
\list
- \o \e{The child of a QObject must always be created in the thread
+ \li \e{The child of a QObject must always be created in the thread
where the parent was created.} This implies, among other
things, that you should never pass the QThread object (\c
this) as the parent of an object created in the thread (since
the QThread object itself was created in another thread).
- \o \e{Event driven objects may only be used in a single thread.}
+ \li \e{Event driven objects may only be used in a single thread.}
Specifically, this applies to the \l{timers.html}{timer
mechanism} and the \l{QtNetwork}{network module}. For example,
you cannot start a timer or connect a socket in a thread that
is not the \l{QObject::thread()}{object's thread}.
- \o \e{You must ensure that all objects created in a thread are
+ \li \e{You must ensure that all objects created in a thread are
deleted before you delete the QThread.} This can be done
easily by creating the objects on the stack in your
\l{QThread::run()}{run()} implementation.
@@ -469,26 +469,26 @@
\list
- \o \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
+ \li \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
emitted in the thread which the receiving object has affinity then
the behavior is the same as the Direct Connection. Otherwise,
the behavior is the same as the Queued Connection."
- \o \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
+ \li \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
immediately, when the signal is emitted. The slot is executed
in the emitter's thread, which is not necessarily the
receiver's thread.
- \o \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
+ \li \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
when control returns to the event loop of the receiver's
thread. The slot is executed in the receiver's thread.
- \o \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
+ \li \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
The slot is invoked as for the Queued Connection, except the
current thread blocks until the slot returns. \note Using this
type to connect objects in the same thread will cause deadlock.
- \o \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
+ \li \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
same as the Auto Connection, but the connection is made only if
it does not duplicate an existing connection. i.e., if the same
signal is already connected to the same slot for the same pair
@@ -546,33 +546,33 @@
\list
- \o QtConcurrent::map() applies a function to every item in a container,
+ \li QtConcurrent::map() applies a function to every item in a container,
modifying the items in-place.
- \o QtConcurrent::mapped() is like map(), except that it returns a new
+ \li QtConcurrent::mapped() is like map(), except that it returns a new
container with the modifications.
- \o QtConcurrent::mappedReduced() is like mapped(), except that the
+ \li QtConcurrent::mappedReduced() is like mapped(), except that the
modified results are reduced or folded into a single result.
- \o QtConcurrent::filter() removes all items from a container based on the
+ \li QtConcurrent::filter() removes all items from a container based on the
result of a filter function.
- \o QtConcurrent::filtered() is like filter(), except that it returns a new
+ \li QtConcurrent::filtered() is like filter(), except that it returns a new
container with the filtered results.
- \o QtConcurrent::filteredReduced() is like filtered(), except that the
+ \li QtConcurrent::filteredReduced() is like filtered(), except that the
filtered results are reduced or folded into a single result.
- \o QtConcurrent::run() runs a function in another thread.
+ \li QtConcurrent::run() runs a function in another thread.
- \o QFuture represents the result of an asynchronous computation.
+ \li QFuture represents the result of an asynchronous computation.
- \o QFutureIterator allows iterating through results available via QFuture.
+ \li QFutureIterator allows iterating through results available via QFuture.
- \o QFutureWatcher allows monitoring a QFuture using signals-and-slots.
+ \li QFutureWatcher allows monitoring a QFuture using signals-and-slots.
- \o QFutureSynchronizer is a convenience class that automatically
+ \li QFutureSynchronizer is a convenience class that automatically
synchronizes several QFutures.
\endlist
@@ -585,29 +585,29 @@
\table
\header
- \o Iterator Type
- \o Example classes
- \o Support status
+ \li Iterator Type
+ \li Example classes
+ \li Support status
\row
- \o Input Iterator
- \o
- \o Not Supported
+ \li Input Iterator
+ \li
+ \li Not Supported
\row
- \o Output Iterator
- \o
- \o Not Supported
+ \li Output Iterator
+ \li
+ \li Not Supported
\row
- \o Forward Iterator
- \o std::slist
- \o Supported
+ \li Forward Iterator
+ \li std::slist
+ \li Supported
\row
- \o Bidirectional Iterator
- \o QLinkedList, std::list
- \o Supported
+ \li Bidirectional Iterator
+ \li QLinkedList, std::list
+ \li Supported
\row
- \o Random Access Iterator
- \o QList, QVector, std::vector
- \o Supported and Recommended
+ \li Random Access Iterator
+ \li QList, QVector, std::vector
+ \li Supported and Recommended
\endtable
Random access iterators can be faster in cases where Qt Concurrent is iterating
diff --git a/doc/src/examples/addressbook.qdoc b/doc/src/examples/addressbook.qdoc
index 02820307e6..51712d49d3 100644
--- a/doc/src/examples/addressbook.qdoc
+++ b/doc/src/examples/addressbook.qdoc
@@ -107,15 +107,15 @@
dimensions of the model. Whereas, \c rowCount()'s value will vary
depending on the number of contacts added to the address book,
\c columnCount()'s value is always 2 because we only need space
- for the \bold Name and \bold Address columns.
+ for the \b Name and \b Address columns.
\note The \c Q_UNUSED() macro prevents the compiler from
generating warnings regarding unused parameters.
\snippet itemviews/addressbook/tablemodel.cpp 1
- The \c data() function returns either a \bold Name or
- \bold {Address}, based on the contents of the model index
+ The \c data() function returns either a \b Name or
+ \b {Address}, based on the contents of the model index
supplied. The row number stored in the model index is used to
reference an item in the list of pairs. Selection is handled
by the QItemSelectionModel, which will be explained with
@@ -124,7 +124,7 @@
\snippet itemviews/addressbook/tablemodel.cpp 2
The \c headerData() function displays the table's header,
- \bold Name and \bold Address. If you require numbered entries
+ \b Name and \b Address. If you require numbered entries
for your address book, you can use a vertical header which we
have hidden in this example (see the \c AddressWidget
implementation).
@@ -372,8 +372,8 @@
menus and actions necessary to manipulate the address book.
\table
- \row \o \inlineimage addressbook-filemenu.png
- \o \inlineimage addressbook-toolsmenu.png
+ \row \li \inlineimage addressbook-filemenu.png
+ \li \inlineimage addressbook-toolsmenu.png
\endtable
\snippet itemviews/addressbook/mainwindow.h 0
diff --git a/doc/src/examples/affine.qdoc b/doc/src/examples/affine.qdoc
index df85576e84..c01031190a 100644
--- a/doc/src/examples/affine.qdoc
+++ b/doc/src/examples/affine.qdoc
@@ -39,10 +39,10 @@
in the following ways:
\list
- \o Dragging the red circle in the centre of each drawing moves it to a new position.
- \o Dragging the displaced red circle causes the current drawing to be rotated about the
+ \li Dragging the red circle in the centre of each drawing moves it to a new position.
+ \li Dragging the displaced red circle causes the current drawing to be rotated about the
central circle. Rotation can also be controlled with the \key Rotate slider.
- \o Scaling is controlled with the \key Scale slider.
- \o Each drawing can be sheared with the \key Shear slider.
+ \li Scaling is controlled with the \key Scale slider.
+ \li Each drawing can be sheared with the \key Shear slider.
\endlist
*/
diff --git a/doc/src/examples/arrowpad.qdoc b/doc/src/examples/arrowpad.qdoc
index ee35aa59ae..79bf94c510 100644
--- a/doc/src/examples/arrowpad.qdoc
+++ b/doc/src/examples/arrowpad.qdoc
@@ -142,18 +142,18 @@
Now, enter the following translations:
\list
- \o \c ArrowPad
+ \li \c ArrowPad
\list
- \o \&Up - \&Haut
- \o \&Left - \&Gauche
- \o \&Right - \&Droite
- \o \&Down - \&Bas
+ \li \&Up - \&Haut
+ \li \&Left - \&Gauche
+ \li \&Right - \&Droite
+ \li \&Down - \&Bas
\endlist
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o E\&xit - \&Quitter
- \o Ctrl+Q - Ctrl+Q
- \o \&File - \&Fichier
+ \li E\&xit - \&Quitter
+ \li Ctrl+Q - Ctrl+Q
+ \li \&File - \&Fichier
\endlist
\endlist
@@ -164,18 +164,18 @@
Save the file and do the same for Dutch working with \c arrowpad_nl.ts:
\list
- \o \c ArrowPad
+ \li \c ArrowPad
\list
- \o \&Up - \&Omhoog
- \o \&Left - \&Links
- \o \&Right - \&Rechts
- \o \&Down - Omlaa\&g
+ \li \&Up - \&Omhoog
+ \li \&Left - \&Links
+ \li \&Right - \&Rechts
+ \li \&Down - Omlaa\&g
\endlist
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o E\&xit - \&Afsluiten
- \o Ctrl+Q - Ctrl+A
- \o File - \&Bestand
+ \li E\&xit - \&Afsluiten
+ \li Ctrl+Q - Ctrl+A
+ \li File - \&Bestand
\endlist
\endlist
diff --git a/doc/src/examples/basicdrawing.qdoc b/doc/src/examples/basicdrawing.qdoc
index 3920811e30..501b791bc1 100644
--- a/doc/src/examples/basicdrawing.qdoc
+++ b/doc/src/examples/basicdrawing.qdoc
@@ -53,9 +53,9 @@
The Basic Drawing example consists of two classes:
\list
- \o \c RenderArea is a custom widget that renders multiple
+ \li \c RenderArea is a custom widget that renders multiple
copies of the currently active shape.
- \o \c Window is the application's main window displaying a
+ \li \c Window is the application's main window displaying a
\c RenderArea widget in addition to several parameter widgets.
\endlist
@@ -415,19 +415,19 @@
the associated QPainter drawing function:
\list
- \o QPainter::drawLine(),
- \o QPainter::drawPoints(),
- \o QPainter::drawPolyline(),
- \o QPainter::drawPolygon(),
- \o QPainter::drawRect(),
- \o QPainter::drawRoundedRect(),
- \o QPainter::drawEllipse(),
- \o QPainter::drawArc(),
- \o QPainter::drawChord(),
- \o QPainter::drawPie(),
- \o QPainter::drawPath(),
- \o QPainter::drawText() or
- \o QPainter::drawPixmap()
+ \li QPainter::drawLine(),
+ \li QPainter::drawPoints(),
+ \li QPainter::drawPolyline(),
+ \li QPainter::drawPolygon(),
+ \li QPainter::drawRect(),
+ \li QPainter::drawRoundedRect(),
+ \li QPainter::drawEllipse(),
+ \li QPainter::drawArc(),
+ \li QPainter::drawChord(),
+ \li QPainter::drawPie(),
+ \li QPainter::drawPath(),
+ \li QPainter::drawText() or
+ \li QPainter::drawPixmap()
\endlist
Before we started rendering, we saved the current painter state
diff --git a/doc/src/examples/basicgraphicslayouts.qdoc b/doc/src/examples/basicgraphicslayouts.qdoc
index c1703c3430..b7023cf9ca 100644
--- a/doc/src/examples/basicgraphicslayouts.qdoc
+++ b/doc/src/examples/basicgraphicslayouts.qdoc
@@ -57,9 +57,9 @@
We repeat the process:
\list
- \o create a new \c LayoutItem,
- \o add the item \c linear, and
- \o provide a stretch factor.
+ \li create a new \c LayoutItem,
+ \li add the item \c linear, and
+ \li provide a stretch factor.
\endlist
\snippet examples/graphicsview/basicgraphicslayouts/window.cpp 1
diff --git a/doc/src/examples/blockingfortuneclient.qdoc b/doc/src/examples/blockingfortuneclient.qdoc
index 34add534d4..6c3be78859 100644
--- a/doc/src/examples/blockingfortuneclient.qdoc
+++ b/doc/src/examples/blockingfortuneclient.qdoc
@@ -38,14 +38,14 @@
\list
- \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
- \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
diff --git a/doc/src/examples/boxes.qdoc b/doc/src/examples/boxes.qdoc
index f2ca92477a..aa34a61bc3 100644
--- a/doc/src/examples/boxes.qdoc
+++ b/doc/src/examples/boxes.qdoc
@@ -37,11 +37,11 @@
Elements in the demo can be controlled using the mouse in the following
ways:
\list
- \o Dragging the mouse while pressing the left mouse button rotates the
+ \li Dragging the mouse while pressing the left mouse button rotates the
box in the center.
- \o Dragging the mouse while pressing the right mouse button rotates the
+ \li Dragging the mouse while pressing the right mouse button rotates the
satellite boxes.
- \o Scrolling the mouse wheel zooms in and out of the scene.
+ \li Scrolling the mouse wheel zooms in and out of the scene.
\endlist
The options pane can be used to fine-tune various parameters in the demo,
diff --git a/doc/src/examples/cachedtable.qdoc b/doc/src/examples/cachedtable.qdoc
index d6b0aa5013..c9945a0efb 100644
--- a/doc/src/examples/cachedtable.qdoc
+++ b/doc/src/examples/cachedtable.qdoc
@@ -66,9 +66,9 @@
in additon to the model and the editor's buttons.
\table 100%
- \header \o Connecting to a Database
+ \header \li Connecting to a Database
\row
- \o
+ \li
Before we can use the \c TableEditor class, we must create a
connection to the database containing the table we want to edit:
@@ -187,8 +187,8 @@
\table 100%
\row
- \o
- \bold {See also:}
+ \li
+ \b {See also:}
A complete list of Qt's SQL \l {Database Classes}, and the \l
{Model/View Programming} documentation.
diff --git a/doc/src/examples/calculator.qdoc b/doc/src/examples/calculator.qdoc
index eb3ccedc35..8eddfa8c4e 100644
--- a/doc/src/examples/calculator.qdoc
+++ b/doc/src/examples/calculator.qdoc
@@ -38,9 +38,9 @@
The example consists of two classes:
\list
- \o \c Calculator is the calculator widget, with all the
+ \li \c Calculator is the calculator widget, with all the
calculator functionality.
- \o \c Button is the widget used for each of the calculator
+ \li \c Button is the widget used for each of the calculator
button. It derives from QToolButton.
\endlist
@@ -85,18 +85,18 @@
display (a QLineEdit), encode the state of the calculator:
\list
- \o \c sumInMemory contains the value stored in the calculator's memory
+ \li \c sumInMemory contains the value stored in the calculator's memory
(using \gui{MS}, \gui{M+}, or \gui{MC}).
- \o \c sumSoFar stores the value accumulated so far. When the user
+ \li \c sumSoFar stores the value accumulated so far. When the user
clicks \gui{=}, \c sumSoFar is recomputed and shown on the
display. \gui{Clear All} resets \c sumSoFar to zero.
- \o \c factorSoFar stores a temporary value when doing
+ \li \c factorSoFar stores a temporary value when doing
multiplications and divisions.
- \o \c pendingAdditiveOperator stores the last additive operator
+ \li \c pendingAdditiveOperator stores the last additive operator
clicked by the user.
- \o \c pendingMultiplicativeOperator stores the last multiplicative operator
+ \li \c pendingMultiplicativeOperator stores the last multiplicative operator
clicked by the user.
- \o \c waitingForOperand is \c true when the calculator is
+ \li \c waitingForOperand is \c true when the calculator is
expecting the user to start typing an operand.
\endlist
@@ -109,16 +109,16 @@
the user enters a mathematical expression.
\table
- \header \o User Input \o Display \o Sum so Far \o Add. Op. \o Factor so Far \o Mult. Op. \o Waiting for Operand?
- \row \o \o 0 \o 0 \o \o \o \o \c true
- \row \o \gui{1} \o 1 \o 0 \o \o \o \o \c false
- \row \o \gui{1 +} \o 1 \o 1 \o \gui{+} \o \o \o \c true
- \row \o \gui{1 + 2} \o 2 \o 1 \o \gui{+} \o \o \o \c false
- \row \o \gui{1 + 2 \unicode{247}} \o 2 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c true
- \row \o \gui{1 + 2 \unicode{247} 3} \o 3 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c false
- \row \o \gui{1 + 2 \unicode{247} 3 -} \o 1.66667 \o 1.66667 \o \gui{-} \o \o \o \c true
- \row \o \gui{1 + 2 \unicode{247} 3 - 4} \o 4 \o 1.66667 \o \gui{-} \o \o \o \c false
- \row \o \gui{1 + 2 \unicode{247} 3 - 4 =} \o -2.33333 \o 0 \o \o \o \o \c true
+ \header \li User Input \li Display \li Sum so Far \li Add. Op. \li Factor so Far \li Mult. Op. \li Waiting for Operand?
+ \row \li \li 0 \li 0 \li \li \li \li \c true
+ \row \li \gui{1} \li 1 \li 0 \li \li \li \li \c false
+ \row \li \gui{1 +} \li 1 \li 1 \li \gui{+} \li \li \li \c true
+ \row \li \gui{1 + 2} \li 2 \li 1 \li \gui{+} \li \li \li \c false
+ \row \li \gui{1 + 2 \unicode{247}} \li 2 \li 1 \li \gui{+} \li 2 \li \gui{\unicode{247}} \li \c true
+ \row \li \gui{1 + 2 \unicode{247} 3} \li 3 \li 1 \li \gui{+} \li 2 \li \gui{\unicode{247}} \li \c false
+ \row \li \gui{1 + 2 \unicode{247} 3 -} \li 1.66667 \li 1.66667 \li \gui{-} \li \li \li \c true
+ \row \li \gui{1 + 2 \unicode{247} 3 - 4} \li 4 \li 1.66667 \li \gui{-} \li \li \li \c false
+ \row \li \gui{1 + 2 \unicode{247} 3 - 4 =} \li -2.33333 \li 0 \li \li \li \li \c true
\endtable
Unary operators, such as \gui Sqrt, require no special handling;
@@ -356,8 +356,8 @@
base class (QToolButton) but modify it in the following ways:
\list
- \o We add 20 to the \l{QSize::height()}{height} component of the size hint.
- \o We make the \l{QSize::width()}{width} component of the size
+ \li We add 20 to the \l{QSize::height()}{height} component of the size hint.
+ \li We make the \l{QSize::width()}{width} component of the size
hint at least as much as the \l{QSize::width()}{height}.
\endlist
diff --git a/doc/src/examples/calendar.qdoc b/doc/src/examples/calendar.qdoc
index d06bed7c6f..aea9805669 100644
--- a/doc/src/examples/calendar.qdoc
+++ b/doc/src/examples/calendar.qdoc
@@ -37,10 +37,10 @@
Specifically, the example demonstrates the following:
\list
- \o Use of a text editor with a text document
- \o Insertion of tables and frames into a document
- \o Navigation within a table
- \o Insert text in different styles
+ \li Use of a text editor with a text document
+ \li Insertion of tables and frames into a document
+ \li Navigation within a table
+ \li Insert text in different styles
\endlist
The rich text editor used to display the document is used within a main window
diff --git a/doc/src/examples/calendarwidget.qdoc b/doc/src/examples/calendarwidget.qdoc
index 7ef99bfc65..0dd20b1491 100644
--- a/doc/src/examples/calendarwidget.qdoc
+++ b/doc/src/examples/calendarwidget.qdoc
@@ -51,28 +51,28 @@
below.
\table
- \header \o Property
- \o Description
- \row \o \l{QCalendarWidget::}{selectedDate}
- \o The currently selected date.
- \row \o \l{QCalendarWidget::}{minimumDate}
- \o The earliest date that can be selected.
- \row \o \l{QCalendarWidget::}{maximumDate}
- \o The latest date that can be selected.
- \row \o \l{QCalendarWidget::}{firstDayOfWeek}
- \o The day that is displayed as the first day of the week
+ \header \li Property
+ \li Description
+ \row \li \l{QCalendarWidget::}{selectedDate}
+ \li The currently selected date.
+ \row \li \l{QCalendarWidget::}{minimumDate}
+ \li The earliest date that can be selected.
+ \row \li \l{QCalendarWidget::}{maximumDate}
+ \li The latest date that can be selected.
+ \row \li \l{QCalendarWidget::}{firstDayOfWeek}
+ \li The day that is displayed as the first day of the week
(usually Sunday or Monday).
- \row \o \l{QCalendarWidget::}{gridVisible}
- \o Whether the grid should be shown.
- \row \o \l{QCalendarWidget::}{selectionMode}
- \o Whether the user can select a date or not.
- \row \o \l{QCalendarWidget::}{horizontalHeaderFormat}
- \o The format of the day names in the horizontal header
+ \row \li \l{QCalendarWidget::}{gridVisible}
+ \li Whether the grid should be shown.
+ \row \li \l{QCalendarWidget::}{selectionMode}
+ \li Whether the user can select a date or not.
+ \row \li \l{QCalendarWidget::}{horizontalHeaderFormat}
+ \li The format of the day names in the horizontal header
(e.g., "M", "Mon", or "Monday").
- \row \o \l{QCalendarWidget::}{verticalHeaderFormat}
- \o The format of the vertical header.
- \row \o \l{QCalendarWidget::}{navigationBarVisible}
- \o Whether the navigation bar at the top of the calendar
+ \row \li \l{QCalendarWidget::}{verticalHeaderFormat}
+ \li The format of the vertical header.
+ \row \li \l{QCalendarWidget::}{navigationBarVisible}
+ \li Whether the navigation bar at the top of the calendar
widget is shown.
\endtable
diff --git a/doc/src/examples/charactermap.qdoc b/doc/src/examples/charactermap.qdoc
index 33652118ef..5fbcae1fad 100644
--- a/doc/src/examples/charactermap.qdoc
+++ b/doc/src/examples/charactermap.qdoc
@@ -43,9 +43,9 @@ that may be unavailable or difficult to locate on their keyboards.
The example consists of the following classes:
\list
-\i \c CharacterWidget displays the available characters in the current
+\li \c CharacterWidget displays the available characters in the current
font and style.
-\i \c MainWindow provides a standard main window that contains font and
+\li \c MainWindow provides a standard main window that contains font and
style information, a view onto the characters, a line edit, and a push
button for submitting text to the clipboard.
\endlist
diff --git a/doc/src/examples/chart.qdoc b/doc/src/examples/chart.qdoc
index 565b1c6c7d..947eddf1c9 100644
--- a/doc/src/examples/chart.qdoc
+++ b/doc/src/examples/chart.qdoc
@@ -37,7 +37,7 @@
relying on the flexibility of the model/view architecture to handle custom editing
and selection features.
- \bold{Note that you only need to create a new view class if your data requires a
+ \b{Note that you only need to create a new view class if your data requires a
specialized representation.} You should first consider using a standard QListView,
QTableView, or QTreeView with a custom QItemDelegate subclass if you need to
represent data in a special way.
@@ -61,10 +61,10 @@
We interpret the data in the following way:
\list
- \o Column 0 contains data in two different roles:
+ \li Column 0 contains data in two different roles:
The \l{Qt::ItemDataRole}{DisplayRole} contains a label, and the
\l{Qt::ItemDataRole}{DecorationRole} contains the color of the pie slice.
- \o Column 1 contains a quantity which we will convert to the angular extent of
+ \li Column 1 contains a quantity which we will convert to the angular extent of
the slice.
\endlist
diff --git a/doc/src/examples/classwizard.qdoc b/doc/src/examples/classwizard.qdoc
index 0fad22e56a..8f84193f2e 100644
--- a/doc/src/examples/classwizard.qdoc
+++ b/doc/src/examples/classwizard.qdoc
@@ -44,10 +44,10 @@
The Class Wizard example consists of the following classes:
\list
- \o \c ClassWizard inherits QWizard and provides a
+ \li \c ClassWizard inherits QWizard and provides a
three-step wizard that generates the skeleton of a C++ class
based on the user's input.
- \o \c IntroPage, \c ClassInfoPage, \c CodeStylePage, \c
+ \li \c IntroPage, \c ClassInfoPage, \c CodeStylePage, \c
OutputFilesPage, and \c ConclusionPage are QWizardPage
subclasses that implement the wizard pages.
\endlist
@@ -61,17 +61,17 @@
five pages:
\list
- \o The first page is an introduction page, telling the user what
+ \li The first page is an introduction page, telling the user what
the wizard is going to do.
- \o The second page asks for a class name and a base class, and
+ \li The second page asks for a class name and a base class, and
allows the user to specify whether the class should have a \c
Q_OBJECT macro and what constructors it should provide.
- \o The third page allows the user to set some options related to the code
+ \li The third page allows the user to set some options related to the code
style, such as the macro used to protect the header file from
multiple inclusion (e.g., \c MYDIALOG_H).
- \o The fourth page allows the user to specify the names of the
+ \li The fourth page allows the user to specify the names of the
output files.
- \o The fifth page is a conclusion page.
+ \li The fifth page is a conclusion page.
\endlist
Although the program is just an example, if you press \gui Finish
diff --git a/doc/src/examples/coloreditorfactory.qdoc b/doc/src/examples/coloreditorfactory.qdoc
index 741db7e387..1806446fb7 100644
--- a/doc/src/examples/coloreditorfactory.qdoc
+++ b/doc/src/examples/coloreditorfactory.qdoc
@@ -134,16 +134,16 @@
Possible suggestions are:
\list
- \o If the editor widget has no user property defined, the delegate
+ \li If the editor widget has no user property defined, the delegate
asks the factory for the property name, which it in turn
asks the item editor creator for. In this case, you can use
the QItemEditorCreator class, which takes the property
name to use for editing as a constructor argument.
- \o If the editor requires other constructors or other
+ \li If the editor requires other constructors or other
initialization than provided by QItemEditorCreatorBase, you
must reimplement
QItemEditorCreatorBase::createWidget().
- \o You could also subclass QItemEditorFactory if you only want
+ \li You could also subclass QItemEditorFactory if you only want
to provide editors for certain kinds of data or use another
method of creating the editors than using creator bases.
\endlist
diff --git a/doc/src/examples/completer.qdoc b/doc/src/examples/completer.qdoc
index 767efe8ef1..df832de4d6 100644
--- a/doc/src/examples/completer.qdoc
+++ b/doc/src/examples/completer.qdoc
@@ -77,8 +77,8 @@
The screenshots below illustrate this difference:
\table
- \row \o \inlineimage completer-example-qdirmodel.png
- \o \inlineimage completer-example-dirmodel.png
+ \row \li \inlineimage completer-example-qdirmodel.png
+ \li \inlineimage completer-example-dirmodel.png
\endtable
The Qt::EditRole, which QCompleter uses to look for matches, is left
diff --git a/doc/src/examples/composition.qdoc b/doc/src/examples/composition.qdoc
index 1da41dbfef..6aca01d255 100644
--- a/doc/src/examples/composition.qdoc
+++ b/doc/src/examples/composition.qdoc
@@ -33,10 +33,10 @@
\image composition-demo.png
- The two most common forms of composition are \bold{Source} and \bold{SourceOver}.
- \bold{Source} is used to draw opaque objects onto a paint device. In this mode,
+ The two most common forms of composition are \b{Source} and \b{SourceOver}.
+ \b{Source} is used to draw opaque objects onto a paint device. In this mode,
each pixel in the source replaces the corresponding pixel in the destination.
- In \bold{SourceOver} composition mode, the source object is transparent and is
+ In \b{SourceOver} composition mode, the source object is transparent and is
drawn on top of the destination.
In addition to these standard modes, Qt defines the complete set of composition modes
diff --git a/doc/src/examples/concentriccircles.qdoc b/doc/src/examples/concentriccircles.qdoc
index 73b4937049..22b0be8fb8 100644
--- a/doc/src/examples/concentriccircles.qdoc
+++ b/doc/src/examples/concentriccircles.qdoc
@@ -59,9 +59,9 @@
The example consists of two classes:
\list
- \o \c CircleWidget is a custom widget which renders several animated
+ \li \c CircleWidget is a custom widget which renders several animated
concentric circles.
- \o \c Window is the application's main window displaying four \c
+ \li \c Window is the application's main window displaying four \c
{CircleWidget}s drawn using different combinations of precision
and aliasing.
\endlist
diff --git a/doc/src/examples/cube.qdoc b/doc/src/examples/cube.qdoc
index 3c41856254..ec40be0f45 100644
--- a/doc/src/examples/cube.qdoc
+++ b/doc/src/examples/cube.qdoc
@@ -61,9 +61,9 @@
The example consist of two classes:
\list
- \o \c MainWidget extends QGLWidget and contains OpenGL ES 2.0
+ \li \c MainWidget extends QGLWidget and contains OpenGL ES 2.0
initialization and drawing and mouse and timer event handling
- \o \c GeometryEngine handles polygon geometries. Transfers polygon geometry
+ \li \c GeometryEngine handles polygon geometries. Transfers polygon geometry
to vertex buffer objects and draws geometries from vertex buffer objects.
\endlist
diff --git a/doc/src/examples/customsortfiltermodel.qdoc b/doc/src/examples/customsortfiltermodel.qdoc
index ac9fbb93a3..61230a7b9a 100644
--- a/doc/src/examples/customsortfiltermodel.qdoc
+++ b/doc/src/examples/customsortfiltermodel.qdoc
@@ -48,10 +48,10 @@
\list
- \o The \c MySortFilterProxyModel class provides a custom proxy
+ \li The \c MySortFilterProxyModel class provides a custom proxy
model.
- \o The \c Window class provides the main application window,
+ \li The \c Window class provides the main application window,
using the custom proxy model to sort and filter a standard
item model.
diff --git a/doc/src/examples/dbscreen.qdoc b/doc/src/examples/dbscreen.qdoc
index 7d9cea5519..bfecb9a3cb 100644
--- a/doc/src/examples/dbscreen.qdoc
+++ b/doc/src/examples/dbscreen.qdoc
@@ -36,13 +36,13 @@
to writing and implementing this graphics driver:
\list 1
- \o \l {Step 1: Creating a Custom Graphics Driver}
+ \li \l {Step 1: Creating a Custom Graphics Driver}
{Creating a Custom Graphics Driver}
- \o \l {Step 2: Implementing the Back Buffer}
+ \li \l {Step 2: Implementing the Back Buffer}
{Implementing the Back Buffer}
- \o \l {Step 3: Creating the Driver Plugin}
+ \li \l {Step 3: Creating the Driver Plugin}
{Creating the Driver Plugin}
\endlist
@@ -71,11 +71,11 @@
functions belonging to QScreen:
\list
- \o \l{QScreen::initDevice()}{initDevice()},
- \o \l{QScreen::shutdownDevice()}{shutdownDevice()},
- \o \l{QScreen::blit()}{blit()},
- \o \l{QScreen::solidFill()}{solidFill()}, and
- \o \l{QScreen::exposeRegion()}{exposeRegion()}.
+ \li \l{QScreen::initDevice()}{initDevice()},
+ \li \l{QScreen::shutdownDevice()}{shutdownDevice()},
+ \li \l{QScreen::blit()}{blit()},
+ \li \l{QScreen::solidFill()}{solidFill()}, and
+ \li \l{QScreen::exposeRegion()}{exposeRegion()}.
\endlist
\snippet examples/qws/dbscreen/dbscreen.h 0
@@ -89,10 +89,10 @@
The graphics driver must carry out three main functions:
\list 1
- \o Allocate the back buffer on startup and deallocate it on shutdown.
- \o Draw to the back buffer instead of directly to the screen
+ \li Allocate the back buffer on startup and deallocate it on shutdown.
+ \li Draw to the back buffer instead of directly to the screen
(which is what QLinuxFbScreen does).
- \o Copy the back buffer to the screen whenever a screen update is
+ \li Copy the back buffer to the screen whenever a screen update is
done.
\endlist
@@ -165,9 +165,9 @@
There are only two functions to reimplement:
\list
- \o \l{QScreenDriverPlugin::create()}{create()} - creates a driver
+ \li \l{QScreenDriverPlugin::create()}{create()} - creates a driver
matching the given key
- \o \l{QScreenDriverPlugin::create()}{keys()} - returns a list of
+ \li \l{QScreenDriverPlugin::create()}{keys()} - returns a list of
valid keys representing the drivers supported by the plugin
\endlist
diff --git a/doc/src/examples/diagramscene.qdoc b/doc/src/examples/diagramscene.qdoc
index 9f2a8f8b76..ac9ca2f294 100644
--- a/doc/src/examples/diagramscene.qdoc
+++ b/doc/src/examples/diagramscene.qdoc
@@ -55,28 +55,28 @@
In particular we show how to:
\list
- \o Create custom graphics items.
- \o Handle mouse events and movement of items.
- \o Implement a graphics scene that can manage our custom items.
- \o Custom painting of items.
- \o Create a movable and editable text item.
+ \li Create custom graphics items.
+ \li Handle mouse events and movement of items.
+ \li Implement a graphics scene that can manage our custom items.
+ \li Custom painting of items.
+ \li Create a movable and editable text item.
\endlist
The example consists of the following classes:
\list
- \o \c MainWindow creates the widgets and display
+ \li \c MainWindow creates the widgets and display
them in a QMainWindow. It also manages the interaction
between the widgets and the graphics scene, view and
items.
- \o \c DiagramItem inherits QGraphicsPolygonItem and
+ \li \c DiagramItem inherits QGraphicsPolygonItem and
represents a flowchart shape.
- \o \c TextDiagramItem inherits QGraphicsTextItem and
+ \li \c TextDiagramItem inherits QGraphicsTextItem and
represents text items in the diagram. The class adds
support for moving the item with the mouse, which is not
supported by QGraphicsTextItem.
- \o \c Arrow inherits QGraphicsLineItem and is an arrow
+ \li \c Arrow inherits QGraphicsLineItem and is an arrow
that connect two DiagramItems.
- \o \c DiagramScene inherits QGraphicsDiagramScene and
+ \li \c DiagramScene inherits QGraphicsDiagramScene and
provides support for \c DiagramItem, \c Arrow and
\c DiagramTextItem (In addition to the support already
handled by QGraphicsScene).
diff --git a/doc/src/examples/drilldown.qdoc b/doc/src/examples/drilldown.qdoc
index 1e7b8c01d6..7f195d5261 100644
--- a/doc/src/examples/drilldown.qdoc
+++ b/doc/src/examples/drilldown.qdoc
@@ -45,13 +45,13 @@
The example consists of three classes:
\list
- \o \c ImageItem is a custom graphics item class used to
+ \li \c ImageItem is a custom graphics item class used to
display the office images.
- \o \c View is the main application widget allowing the user to
+ \li \c View is the main application widget allowing the user to
browse through the various locations.
- \o \c InformationWindow displays the requested information,
+ \li \c InformationWindow displays the requested information,
allowing the users to alter it and submit their changes to the
database.
\endlist
diff --git a/doc/src/examples/dropsite.qdoc b/doc/src/examples/dropsite.qdoc
index 024d191b74..77b40986aa 100644
--- a/doc/src/examples/dropsite.qdoc
+++ b/doc/src/examples/dropsite.qdoc
@@ -53,10 +53,10 @@
reimplementations of four \l{QWidget} event handlers:
\list 1
- \o \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
- \o \l{QWidget::dragMoveEvent()}{dragMoveEvent()}
- \o \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()}
- \o \l{QWidget::dropEvent()}{dropEvent()}
+ \li \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
+ \li \l{QWidget::dragMoveEvent()}{dragMoveEvent()}
+ \li \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()}
+ \li \l{QWidget::dropEvent()}{dropEvent()}
\endlist
These event handlers are further explained in the implementation of the
@@ -108,17 +108,17 @@
\snippet draganddrop/dropsite/droparea.cpp dropEvent() function part2
\list
- \o If \c mimeData contains an image, we display it in \c DropArea with
+ \li If \c mimeData contains an image, we display it in \c DropArea with
\l{QLabel::setPixmap()}{setPixmap()}.
- \o If \c mimeData contains HTML, we display it with
+ \li If \c mimeData contains HTML, we display it with
\l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format
as Qt::RichText.
- \o If \c mimeData contains plain text, we display it with
+ \li If \c mimeData contains plain text, we display it with
\l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format
as Qt::PlainText. In the event that \c mimeData contains URLs, we
iterate through the list of URLs to display them on individual
lines.
- \o If \c mimeData contains other types of objects, we set
+ \li If \c mimeData contains other types of objects, we set
\c{DropArea}'s text, with \l{QLabel::setText()}{setText()} to
"Cannot display data" to inform the user.
\endlist
diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc
index 306295842e..958080ad58 100644
--- a/doc/src/examples/editabletreemodel.qdoc
+++ b/doc/src/examples/editabletreemodel.qdoc
@@ -82,8 +82,8 @@
\target Relations-between-internal-items
\table
- \row \o \inlineimage itemviews-editabletreemodel-items.png
- \o \bold{Relations between internal items}
+ \row \li \inlineimage itemviews-editabletreemodel-items.png
+ \li \b{Relations between internal items}
When designing a data structure for use with a custom model, it is useful
to expose each item's parent via a function like
@@ -99,10 +99,10 @@
\l{TreeItem::parent}{parent()} and \l{TreeItem::child}{child()}
functions.
- In the example shown, two top-level items, \bold{A} and
- \bold{B}, can be obtained from the root item by calling its child()
+ In the example shown, two top-level items, \b{A} and
+ \b{B}, can be obtained from the root item by calling its child()
function, and each of these items return the root node from their
- parent() functions, though this is only shown for item \bold{A}.
+ parent() functions, though this is only shown for item \b{A}.
\endtable
Each \c TreeItem stores data for each column in the row it represents
@@ -126,23 +126,23 @@
horizontal header titles.
\table
- \row \o \inlineimage itemviews-editabletreemodel-model.png
- \o \bold{Accessing data via the model}
+ \row \li \inlineimage itemviews-editabletreemodel-model.png
+ \li \b{Accessing data via the model}
In the case shown in the diagram, the piece of information represented
- by \bold{a} can be obtained using the standard model/view API:
+ by \b{a} can be obtained using the standard model/view API:
\snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 0
Since each items holds pieces of data for each column in a given row,
there can be many model indexes that map to the same \c TreeItem object.
- For example, the information represented by \bold{b} can be obtained
+ For example, the information represented by \b{b} can be obtained
using the following code:
\snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 1
The same underlying \c TreeItem would be accessed to obtain information
- for the other model indexes in the same row as \bold{b}.
+ for the other model indexes in the same row as \b{b}.
\endtable
In the model class, \c TreeModel, we relate \c TreeItem objects to
@@ -166,20 +166,20 @@
that the model does not attempt to access items that have been deleted.
\table
- \row \o \bold{Storing information in the underlying data structure}
+ \row \li \b{Storing information in the underlying data structure}
Several pieces of data are stored as QVariant objects in the \c itemData
member of each \c TreeItem instance
The diagram shows how pieces of information,
- represented by the labels \bold{a}, \bold{b} and \bold{c} in the
- previous two diagrams, are stored in items \bold{A}, \bold{B} and
- \bold{C} in the underlying data structure. Note that pieces of
+ represented by the labels \b{a}, \b{b} and \b{c} in the
+ previous two diagrams, are stored in items \b{A}, \b{B} and
+ \b{C} in the underlying data structure. Note that pieces of
information from the same row in the model are all obtained from the
same item. Each element in a list corresponds to a piece of information
exposed by each column in a given row in the model.
- \o \inlineimage itemviews-editabletreemodel-values.png
+ \li \inlineimage itemviews-editabletreemodel-values.png
\endtable
Since the \c TreeModel implementation has been designed for use with
@@ -202,8 +202,8 @@
\target Relating-items-using-model-indexes
\table
\row
- \o \inlineimage itemviews-editabletreemodel-indexes.png
- \o \bold{Relating items using model indexes}
+ \li \inlineimage itemviews-editabletreemodel-indexes.png
+ \li \b{Relating items using model indexes}
As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
the \c TreeModel needs to be able to take a model index, find the
@@ -215,13 +215,13 @@
an item supplied by the caller, using the items shown in a
\l{Relations-between-internal-items}{previous diagram}.
- A pointer to item \bold{C} is obtained from the corresponding model index
+ A pointer to item \b{C} is obtained from the corresponding model index
using the \l{QModelIndex::internalPointer()} function. The pointer was
stored internally in the index when it was created. Since the child
contains a pointer to its parent, we use its \l{TreeItem::parent}{parent()}
- function to obtain a pointer to item \bold{B}. The parent model index is
+ function to obtain a pointer to item \b{B}. The parent model index is
created using the QAbstractItemModel::createIndex() function, passing
- the pointer to item \bold{B} as the internal pointer.
+ the pointer to item \b{B} as the internal pointer.
\endtable
\section1 TreeItem Class Definition
diff --git a/doc/src/examples/elasticnodes.qdoc b/doc/src/examples/elasticnodes.qdoc
index 51a0a6048a..bd25008f60 100644
--- a/doc/src/examples/elasticnodes.qdoc
+++ b/doc/src/examples/elasticnodes.qdoc
@@ -54,9 +54,9 @@
The \c Node class serves three purposes:
\list
- \o Painting a yellow gradient "ball" in two states: sunken and raised.
- \o Managing connections to other nodes.
- \o Calculating forces pulling and pushing the nodes in the grid.
+ \li Painting a yellow gradient "ball" in two states: sunken and raised.
+ \li Managing connections to other nodes.
+ \li Calculating forces pulling and pushing the nodes in the grid.
\endlist
Let's start by looking at the \c Node class declaration.
diff --git a/doc/src/examples/fortuneclient.qdoc b/doc/src/examples/fortuneclient.qdoc
index f2c6fa02d9..d997fc077e 100644
--- a/doc/src/examples/fortuneclient.qdoc
+++ b/doc/src/examples/fortuneclient.qdoc
@@ -47,14 +47,14 @@
\list
- \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
- \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
@@ -107,11 +107,11 @@
one of two things can happen:
\list
- \o \e{The connection is established.} In this case, the server will send us a
+ \li \e{The connection is established.} In this case, the server will send us a
fortune. QTcpSocket will emit \l{QTcpSocket::readyRead()}{readyRead()}
every time it receives a block of data.
- \o \e{An error occurs.} We need to inform the user if the connection
+ \li \e{An error occurs.} We need to inform the user if the connection
failed or was broken. In this case, QTcpSocket will emit
\l{QTcpSocket::error()}{error()}, and \c Client::displayError() will be
called.
diff --git a/doc/src/examples/fridgemagnets.qdoc b/doc/src/examples/fridgemagnets.qdoc
index b2bd440707..7b7218bba2 100644
--- a/doc/src/examples/fridgemagnets.qdoc
+++ b/doc/src/examples/fridgemagnets.qdoc
@@ -39,9 +39,9 @@
the words on the magnets. The example consists of two classes:
\list
- \o \c DragLabel is a custom widget representing one
+ \li \c DragLabel is a custom widget representing one
single fridge magnet.
- \o \c DragWidget provides the main application window.
+ \li \c DragWidget provides the main application window.
\endlist
We will first take a look at the \c DragLabel class, then we will
diff --git a/doc/src/examples/gradients.qdoc b/doc/src/examples/gradients.qdoc
index 75876fdf2c..75f78b56ea 100644
--- a/doc/src/examples/gradients.qdoc
+++ b/doc/src/examples/gradients.qdoc
@@ -37,10 +37,10 @@
There are three types of gradients:
\list
- \o \bold{Linear} gradients interpolate colors between start and end points.
- \o \bold{Radial} gradients interpolate colors between a focal point and the
+ \li \b{Linear} gradients interpolate colors between start and end points.
+ \li \b{Radial} gradients interpolate colors between a focal point and the
points on a circle surrounding it.
- \o \bold{Conical} gradients interpolate colors around a center point.
+ \li \b{Conical} gradients interpolate colors around a center point.
\endlist
The panel on the right contains a color table editor that defines
diff --git a/doc/src/examples/hellogl.qdoc b/doc/src/examples/hellogl.qdoc
index a0b6fc6c06..f6f8591ad0 100644
--- a/doc/src/examples/hellogl.qdoc
+++ b/doc/src/examples/hellogl.qdoc
@@ -285,12 +285,12 @@
by reimplementing the following functions:
\list
- \o QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
+ \li QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
to render the scene.
- \o QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
+ \li QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport
coordinates.
- \o QGLWidget::paintGL() performs painting operations using OpenGL calls.
+ \li QGLWidget::paintGL() performs painting operations using OpenGL calls.
\endlist
Since QGLWidget is a subclass of QWidget, it can also be used
diff --git a/doc/src/examples/icons.qdoc b/doc/src/examples/icons.qdoc
index be7b0dd46c..9e7dda7c89 100644
--- a/doc/src/examples/icons.qdoc
+++ b/doc/src/examples/icons.qdoc
@@ -47,24 +47,24 @@
of the icon. Qt currently defines four modes:
\table
- \header \o Mode \o Description
+ \header \li Mode \li Description
\row
- \o QIcon::Normal
- \o Display the pixmap when the user is not interacting with the
+ \li QIcon::Normal
+ \li Display the pixmap when the user is not interacting with the
icon, but the functionality represented by the icon is
available.
\row
- \o QIcon::Active
- \o Display the pixmap when the functionality represented by the
+ \li QIcon::Active
+ \li Display the pixmap when the functionality represented by the
icon is available and the user is interacting with the icon,
for example, moving the mouse over it or clicking it.
\row
- \o QIcon::Disabled
- \o Display the pixmap when the functionality represented by
+ \li QIcon::Disabled
+ \li Display the pixmap when the functionality represented by
the icon is not available.
\row
- \o QIcon::Selected
- \o Display the pixmap when the icon is selected.
+ \li QIcon::Selected
+ \li Display the pixmap when the icon is selected.
\endtable
QIcon's states are QIcon::On and QIcon::Off, which will display
@@ -148,16 +148,16 @@
search algorithm described in the table below:
\table 100%
- \header \o{2,1} Requested Pixmap \o {8,1} Preferred Alternatives (mode/state)
- \header \o Mode \o State \o 1 \o 2 \o 3 \o 4 \o 5 \o 6 \o 7 \o 8
- \row \o{1,2} Normal \o Off \o \bold N0 \o A0 \o N1 \o A1 \o D0 \o S0 \o D1 \o S1
- \row \o On \o N1 \o \bold A1 \o N0 \o A0 \o D1 \o S1 \o D0 \o S0
- \row \o{1,2} Active \o Off \o A0 \o \bold N0 \o A1 \o N1 \o D0 \o S0 \o D1 \o S1
- \row \o On \o \bold A1 \o N1 \o A0 \o N0 \o D1 \o S1 \o D0 \o S0
- \row \o{1,2} Disabled \o Off \o D0 \o \bold {N0'} \o A0' \o D1 \o N1' \o A1' \o S0' \o S1'
- \row \o On \o D1 \o N1' \o \bold {A1'} \o D0 \o N0' \o A0' \o S1' \o S0'
- \row \o{1,2} Selected \o Off \o S0 \o \bold {N0''} \o A0'' \o S1 \o N1'' \o A1'' \o D0'' \o D1''
- \row \o On \o S1 \o N1'' \o \bold {A1''} \o S0 \o N0'' \o A0'' \o D1'' \o D0''
+ \header \li{2,1} Requested Pixmap \li {8,1} Preferred Alternatives (mode/state)
+ \header \li Mode \li State \li 1 \li 2 \li 3 \li 4 \li 5 \li 6 \li 7 \li 8
+ \row \li{1,2} Normal \li Off \li \b N0 \li A0 \li N1 \li A1 \li D0 \li S0 \li D1 \li S1
+ \row \li On \li N1 \li \b A1 \li N0 \li A0 \li D1 \li S1 \li D0 \li S0
+ \row \li{1,2} Active \li Off \li A0 \li \b N0 \li A1 \li N1 \li D0 \li S0 \li D1 \li S1
+ \row \li On \li \b A1 \li N1 \li A0 \li N0 \li D1 \li S1 \li D0 \li S0
+ \row \li{1,2} Disabled \li Off \li D0 \li \b {N0'} \li A0' \li D1 \li N1' \li A1' \li S0' \li S1'
+ \row \li On \li D1 \li N1' \li \b {A1'} \li D0 \li N0' \li A0' \li S1' \li S0'
+ \row \li{1,2} Selected \li Off \li S0 \li \b {N0''} \li A0'' \li S1 \li N1'' \li A1'' \li D0'' \li D1''
+ \row \li On \li S1 \li N1'' \li \b {A1''} \li S0 \li N0'' \li A0'' \li D1'' \li D0''
\endtable
In the table, "0" and "1" stand for Off" and "On", respectively.
@@ -176,8 +176,8 @@
\table
\row
- \o \inlineimage icons_monkey.png Screenshot of the Monkey Files
- \o \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
+ \li \inlineimage icons_monkey.png Screenshot of the Monkey Files
+ \li \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
\endtable
For any given mode/state combination, it is possible to specify
@@ -193,25 +193,25 @@
\table
\row
- \o
- \o \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
- \o \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
- \o \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
+ \li
+ \li \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
+ \li \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
+ \li \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
\row
- \o
- \o 8 x 8
- \o \bold {16 x 16}
- \o 17 x 17
+ \li
+ \li 8 x 8
+ \li \b {16 x 16}
+ \li 17 x 17
\row
- \o \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
- \o \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
- \o \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
- \o \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
+ \li \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
+ \li \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
+ \li \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
+ \li \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
\row
- \o \bold {32 x 32}
- \o 33 x 33
- \o \bold {48 x 48}
- \o 64 x 64
+ \li \b {32 x 32}
+ \li 33 x 33
+ \li \b {48 x 48}
+ \li 64 x 64
\endtable
For sizes up to 16 x 16, QIcon uses \c qt_extended_16x16.png and
@@ -224,13 +224,13 @@
The Icons example consists of four classes:
\list
- \o \c MainWindow inherits QMainWindow and is the main application
+ \li \c MainWindow inherits QMainWindow and is the main application
window.
- \o \c IconPreviewArea is a custom widget that displays all
+ \li \c IconPreviewArea is a custom widget that displays all
combinations of states and modes for a given icon.
- \o \c IconSizeSpinBox is a subclass of QSpinBox that lets the
+ \li \c IconSizeSpinBox is a subclass of QSpinBox that lets the
user enter icon sizes (e.g., "48 x 48").
- \o \c ImageDelegate is a subclass of QItemDelegate that provides
+ \li \c ImageDelegate is a subclass of QItemDelegate that provides
comboboxes for letting the user set the mode and state
associated with an image.
\endlist
@@ -332,13 +332,13 @@
constructor, and declare several private slots:
\list
- \o The \c about() slot simply provides information about the example.
- \o The \c changeStyle() slot changes the application's GUI style and
+ \li The \c about() slot simply provides information about the example.
+ \li The \c changeStyle() slot changes the application's GUI style and
adjust the style dependent size options.
- \o The \c changeSize() slot changes the size of the preview area's icon.
- \o The \c changeIcon() slot updates the set of pixmaps available to the
+ \li The \c changeSize() slot changes the size of the preview area's icon.
+ \li The \c changeIcon() slot updates the set of pixmaps available to the
icon displayed in the preview area.
- \o The \c addImage() slot allows the user to load a new image into the
+ \li The \c addImage() slot allows the user to load a new image into the
application.
\endlist
diff --git a/doc/src/examples/imagecomposition.qdoc b/doc/src/examples/imagecomposition.qdoc
index edefcface4..d7700858a0 100644
--- a/doc/src/examples/imagecomposition.qdoc
+++ b/doc/src/examples/imagecomposition.qdoc
@@ -86,11 +86,11 @@
We connect the following signals to their corresponding slots:
\list
- \o \c{sourceButton}'s \l{QPushButton::clicked()}{clicked()} signal is
+ \li \c{sourceButton}'s \l{QPushButton::clicked()}{clicked()} signal is
connected to \c chooseSource(),
- \o \c{operatorComboBox}'s \l{QComboBox::activated()}{activated()}
+ \li \c{operatorComboBox}'s \l{QComboBox::activated()}{activated()}
signal is connected to \c recalculateResult(), and
- \o \c{destinationButton}'s \l{QToolButton::clicked()}{clicked()} signal
+ \li \c{destinationButton}'s \l{QToolButton::clicked()}{clicked()} signal
is connected to \c chooseDestination().
\endlist
diff --git a/doc/src/examples/imageviewer.qdoc b/doc/src/examples/imageviewer.qdoc
index 18cdccb5ed..638c0c3fb4 100644
--- a/doc/src/examples/imageviewer.qdoc
+++ b/doc/src/examples/imageviewer.qdoc
@@ -49,18 +49,18 @@
to:
\list
- \o \gui{Open...} - Open an image file
- \o \gui{Print...} - Print an image
- \o \gui{Exit} - Exit the application
+ \li \gui{Open...} - Open an image file
+ \li \gui{Print...} - Print an image
+ \li \gui{Exit} - Exit the application
\endlist
Once an image is loaded, the \gui View menu allows the users to:
\list
- \o \gui{Zoom In} - Scale the image up by 25%
- \o \gui{Zoom Out} - Scale the image down by 25%
- \o \gui{Normal Size} - Show the image at its original size
- \o \gui{Fit to Window} - Stretch the image to occupy the entire window
+ \li \gui{Zoom In} - Scale the image up by 25%
+ \li \gui{Zoom Out} - Scale the image down by 25%
+ \li \gui{Normal Size} - Show the image at its original size
+ \li \gui{Fit to Window} - Stretch the image to occupy the entire window
\endlist
In addition the \gui Help menu provides the users with information
@@ -202,9 +202,9 @@
\table
\row
- \o \inlineimage imageviewer-original_size.png
- \o \inlineimage imageviewer-zoom_in_1.png
- \o \inlineimage imageviewer-zoom_in_2.png
+ \li \inlineimage imageviewer-original_size.png
+ \li \inlineimage imageviewer-zoom_in_1.png
+ \li \inlineimage imageviewer-zoom_in_2.png
\endtable
\snippet examples/widgets/imageviewer/imageviewer.cpp 11
@@ -246,9 +246,9 @@
\table
\row
- \o \inlineimage imageviewer-original_size.png
- \o \inlineimage imageviewer-fit_to_window_1.png
- \o \inlineimage imageviewer-fit_to_window_2.png
+ \li \inlineimage imageviewer-original_size.png
+ \li \inlineimage imageviewer-fit_to_window_1.png
+ \li \inlineimage imageviewer-fit_to_window_2.png
\endtable
If the slot is called to turn off the option, the
diff --git a/doc/src/examples/licensewizard.qdoc b/doc/src/examples/licensewizard.qdoc
index 92e51dec3b..3a325100a7 100644
--- a/doc/src/examples/licensewizard.qdoc
+++ b/doc/src/examples/licensewizard.qdoc
@@ -50,10 +50,10 @@
The example consists of the following classes:
\list
- \o \c LicenseWizard inherits QWizard and implements a non-linear
+ \li \c LicenseWizard inherits QWizard and implements a non-linear
five-page wizard that leads the user through the process of
choosing a license agreement.
- \o \c IntroPage, \c EvaluatePage, \c RegisterPage, \c
+ \li \c IntroPage, \c EvaluatePage, \c RegisterPage, \c
DetailsPage, and \c ConclusionPage are QWizardPage subclasses
that implement the wizard pages.
\endlist
@@ -71,12 +71,12 @@
The enum defines the IDs associated with the various pages:
\table
- \header \o Class name \o Enum value \o Page ID
- \row \o \c IntroPage \o \c Page_Intro \o 0
- \row \o \c EvaluatePage \o \c Page_Evaluate \o 1
- \row \o \c RegisterPage \o \c Page_Register \o 2
- \row \o \c DetailsPage \o \c Page_Details \o 3
- \row \o \c ConclusionPage \o \c Page_Conclusion \o 4
+ \header \li Class name \li Enum value \li Page ID
+ \row \li \c IntroPage \li \c Page_Intro \li 0
+ \row \li \c EvaluatePage \li \c Page_Evaluate \li 1
+ \row \li \c RegisterPage \li \c Page_Register \li 2
+ \row \li \c DetailsPage \li \c Page_Details \li 3
+ \row \li \c ConclusionPage \li \c Page_Conclusion \li 4
\endtable
For this example, the IDs are arbitrary. The only constraints are
@@ -206,11 +206,11 @@
QWidget::setVisible():
\list
- \o If the page is shown, we set the \l{QWizard::}{CustomButton1} button's
+ \li If the page is shown, we set the \l{QWizard::}{CustomButton1} button's
text to \gui{\underline{P}rint}, we enable the \l{QWizard::}{HaveCustomButton1}
option, and we connect the QWizard's \l{QWizard::}{customButtonClicked()}
signal to our \c printButtonClicked() slot.
- \o If the page is hidden, we disable the \l{QWizard::}{HaveCustomButton1}
+ \li If the page is hidden, we disable the \l{QWizard::}{HaveCustomButton1}
option and disconnect the \c printButtonClicked() slot.
\endlist
diff --git a/doc/src/examples/maemovibration.qdoc b/doc/src/examples/maemovibration.qdoc
index 855793cf75..78bb7f5334 100644
--- a/doc/src/examples/maemovibration.qdoc
+++ b/doc/src/examples/maemovibration.qdoc
@@ -47,11 +47,11 @@
The code makes use of two classes:
\list
- \o \c MceVibrator connects to the MCE service and can start a certain
+ \li \c MceVibrator connects to the MCE service and can start a certain
vibrator pattern. It also is responsible to parse the configuration
file.
- \o \c ButtonWidget provides a button for each pattern. Pressing the button
+ \li \c ButtonWidget provides a button for each pattern. Pressing the button
activates the pattern in question.
\endlist
@@ -68,10 +68,10 @@
are available to us.
\list
- \o \c mceInterface is our D-Bus handle to the MCE service. We use it to
+ \li \c mceInterface is our D-Bus handle to the MCE service. We use it to
invoke methods on the MCE request object.
- \o \c lastPatternName contains the pattern that was activated last time. We
+ \li \c lastPatternName contains the pattern that was activated last time. We
have to keep track of this, because the last pattern has to be
deactivated before activating a new pattern.
\endlist
diff --git a/doc/src/examples/mandelbrot.qdoc b/doc/src/examples/mandelbrot.qdoc
index 23e51ba637..a560766bdd 100644
--- a/doc/src/examples/mandelbrot.qdoc
+++ b/doc/src/examples/mandelbrot.qdoc
@@ -66,9 +66,9 @@
\table
\row
- \o \inlineimage mandelbrot_zoom1.png
- \o \inlineimage mandelbrot_zoom2.png
- \o \inlineimage mandelbrot_zoom3.png
+ \li \inlineimage mandelbrot_zoom1.png
+ \li \inlineimage mandelbrot_zoom2.png
+ \li \inlineimage mandelbrot_zoom3.png
\endtable
Similarly, when the user scrolls, the previous pixmap is scrolled
@@ -77,17 +77,17 @@
\table
\row
- \o \inlineimage mandelbrot_scroll1.png
- \o \inlineimage mandelbrot_scroll2.png
- \o \inlineimage mandelbrot_scroll3.png
+ \li \inlineimage mandelbrot_scroll1.png
+ \li \inlineimage mandelbrot_scroll2.png
+ \li \inlineimage mandelbrot_scroll3.png
\endtable
The application consists of two classes:
\list
- \o \c RenderThread is a QThread subclass that renders
+ \li \c RenderThread is a QThread subclass that renders
the Mandelbrot set.
- \o \c MandelbrotWidget is a QWidget subclass that shows the
+ \li \c MandelbrotWidget is a QWidget subclass that shows the
Mandelbrot set on screen and lets the user zoom and scroll.
\endlist
diff --git a/doc/src/examples/mousecalibration.qdoc b/doc/src/examples/mousecalibration.qdoc
index b42d95956e..39b9140f28 100644
--- a/doc/src/examples/mousecalibration.qdoc
+++ b/doc/src/examples/mousecalibration.qdoc
@@ -39,8 +39,8 @@
The example consists of two classes in addition to the main program:
\list
- \o \c Calibration is a dialog widget that retrieves the device coordinates.
- \o \c ScribbleWidget is a minimal drawing program used to let the user
+ \li \c Calibration is a dialog widget that retrieves the device coordinates.
+ \li \c ScribbleWidget is a minimal drawing program used to let the user
test the new mouse settings.
\endlist
diff --git a/doc/src/examples/moveblocks.qdoc b/doc/src/examples/moveblocks.qdoc
index d3332be834..38551abd28 100644
--- a/doc/src/examples/moveblocks.qdoc
+++ b/doc/src/examples/moveblocks.qdoc
@@ -40,14 +40,14 @@
The example consists of the following classes:
\list
- \o \c StateSwitcher inherits QState and can add
+ \li \c StateSwitcher inherits QState and can add
\c {StateSwitchTransition}s to other states.
When entered, it will randomly transition to one of these
states.
- \o \c StateSwitchTransition is a custom transition that
+ \li \c StateSwitchTransition is a custom transition that
triggers on \c{StateSwitchEvent}s.
- \o \c StateSwitchEvent is a QEvent that triggers \c{StateSwitchTransition}s.
- \o \c QGraphicsRectWidget is a QGraphicsWidget that simply
+ \li \c StateSwitchEvent is a QEvent that triggers \c{StateSwitchTransition}s.
+ \li \c QGraphicsRectWidget is a QGraphicsWidget that simply
paints its background in a solid \l{Qt::}{blue} color.
\endlist
diff --git a/doc/src/examples/orderform.qdoc b/doc/src/examples/orderform.qdoc
index de967ecebd..94e4914444 100644
--- a/doc/src/examples/orderform.qdoc
+++ b/doc/src/examples/orderform.qdoc
@@ -161,21 +161,21 @@
\table
\row
- \o {1, 8} frame with \e{referenceFrameFormat}
+ \li {1, 8} frame with \e{referenceFrameFormat}
\row
- \o block \o \c{A company}
+ \li block \li \c{A company}
\row
- \o block
+ \li block
\row
- \o block \o \c{321 City Street}
+ \li block \li \c{321 City Street}
\row
- \o block
+ \li block
\row
- \o block \o \c{Industry Park}
+ \li block \li \c{Industry Park}
\row
- \o block
+ \li block
\row
- \o block \o \c{Another country}
+ \li block \li \c{Another country}
\endtable
This is accomplished with the following code:
@@ -196,11 +196,11 @@
\table
\row
- \o block \o \c{Donald}
+ \li block \li \c{Donald}
\row
- \o block \o \c{47338 Park Avenue}
+ \li block \li \c{47338 Park Avenue}
\row
- \o block \o \c{Big City}
+ \li block \li \c{Big City}
\endtable
For spacing purposes, we invoke \l{QTextCursor::insertBlock()}
@@ -221,21 +221,21 @@
\table
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block \o \c{Date: 25 May 2007}
+ \li block \li \c{Date: 25 May 2007}
\row
- \o block
+ \li block
\row
- \o {1, 4} frame with \e{bodyFrameFormat}
+ \li {1, 4} frame with \e{bodyFrameFormat}
\row
- \o block \o \c{I would like to place an order for the following items:}
+ \li block \li \c{I would like to place an order for the following items:}
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\endtable
A QTextTableFormat object, \c orderTableFormat, is used to hold the type
@@ -257,27 +257,27 @@
\table
\row
- \o {1, 11} \c{orderTable} with \e{orderTableFormat}
+ \li {1, 11} \c{orderTable} with \e{orderTableFormat}
\row
- \o block \o \c{Product}
+ \li block \li \c{Product}
\row
- \o block \o \c{Quantity}
+ \li block \li \c{Quantity}
\row
- \o block \o \c{T-shirt}
+ \li block \li \c{T-shirt}
\row
- \o block \o \c{4}
+ \li block \li \c{4}
\row
- \o block \o \c{Badge}
+ \li block \li \c{Badge}
\row
- \o block \o \c{3}
+ \li block \li \c{3}
\row
- \o block \o \c{Reference book}
+ \li block \li \c{Reference book}
\row
- \o block \o \c{2}
+ \li block \li \c{2}
\row
- \o block \o \c{Coffee cup}
+ \li block \li \c{Coffee cup}
\row
- \o block \o \c{5}
+ \li block \li \c{5}
\endtable
The \c cursor is then moved back to \c{topFrame}'s
@@ -296,19 +296,19 @@
\table
\row
- \o block
+ \li block
\row
- \o block\o \c{Please update my...}
+ \li block\li \c{Please update my...}
\row
- \o {1, 5} block
+ \li {1, 5} block
\row
- \o {1, 4} \c{offersTable}
+ \li {1, 4} \c{offersTable}
\row
- \o block \o \c{I want to receive...}
+ \li block \li \c{I want to receive...}
\row
- \o block \o \c{I do not want to receive...}
+ \li block \li \c{I do not want to receive...}
\row
- \o block \o \c{X}
+ \li block \li \c{X}
\endtable
The \c cursor is moved to insert "Sincerely" along with the customer's
@@ -321,17 +321,17 @@
\table
\row
- \o block
+ \li block
\row
- \o {1, 5} block\o \c{Sincerely,}
+ \li {1, 5} block\li \c{Sincerely,}
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block \o \c{Donald}
+ \li block \li \c{Donald}
\endtable
The \c createSample() function is used for illustration purposes, to create
diff --git a/doc/src/examples/overpainting.qdoc b/doc/src/examples/overpainting.qdoc
index 74f9f0a872..d20ee64698 100644
--- a/doc/src/examples/overpainting.qdoc
+++ b/doc/src/examples/overpainting.qdoc
@@ -214,30 +214,30 @@
calls, using the following approach:
\list
- \o Reimplement QGLWidget::initializeGL(), but only perform minimal
+ \li Reimplement QGLWidget::initializeGL(), but only perform minimal
initialization. QPainter will perform its own initialization
routines, modifying the matrix and property stacks, so it is better
to defer certain initialization tasks until just before you render
the 3D scene.
- \o Reimplement QGLWidget::resizeGL() as in the pure 3D case.
- \o Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics.
+ \li Reimplement QGLWidget::resizeGL() as in the pure 3D case.
+ \li Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics.
\endlist
The \l{QWidget::paintEvent()}{paintEvent()} implementation performs the
following tasks:
\list
- \o Push the current OpenGL modelview matrix onto a stack.
- \o Perform initialization tasks usually done in the
+ \li Push the current OpenGL modelview matrix onto a stack.
+ \li Perform initialization tasks usually done in the
\l{QGLWidget::initializeGL()}{initializeGL()} function.
- \o Perform code that would normally be located in the widget's
+ \li Perform code that would normally be located in the widget's
\l{QGLWidget::resizeGL()}{resizeGL()} function to set the correct
perspective transformation and set up the viewport.
- \o Render the scene using OpenGL calls.
- \o Pop the OpenGL modelview matrix off the stack.
- \o Construct a QPainter object.
- \o Initialize it for use on the widget with the QPainter::begin() function.
- \o Draw primitives using QPainter's member functions.
- \o Call QPainter::end() to finish painting.
+ \li Render the scene using OpenGL calls.
+ \li Pop the OpenGL modelview matrix off the stack.
+ \li Construct a QPainter object.
+ \li Initialize it for use on the widget with the QPainter::begin() function.
+ \li Draw primitives using QPainter's member functions.
+ \li Call QPainter::end() to finish painting.
\endlist
*/
diff --git a/doc/src/examples/padnavigator.qdoc b/doc/src/examples/padnavigator.qdoc
index 52d80adcb7..840c16b0c9 100644
--- a/doc/src/examples/padnavigator.qdoc
+++ b/doc/src/examples/padnavigator.qdoc
@@ -81,11 +81,11 @@
The private data members are:
\list
- \o \c pix: The optional pixmap that is drawn on top of the rectangle.
- \o \c fillRect: Corresponds to the \c fill property.
- \o \c color: The configurable gradient color fill of the rectangle.
- \o \c bounds: The bounds of the rectangle.
- \o \c gradient: A precalculated gradient used to fill the rectangle.
+ \li \c pix: The optional pixmap that is drawn on top of the rectangle.
+ \li \c fillRect: Corresponds to the \c fill property.
+ \li \c color: The configurable gradient color fill of the rectangle.
+ \li \c bounds: The bounds of the rectangle.
+ \li \c gradient: A precalculated gradient used to fill the rectangle.
\endlist
We will now review the \c RoundRectItem implementation. Let's start by
@@ -320,13 +320,13 @@
QGraphicsRotation object for each of these.
\list
- \o \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
+ \li \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
animated from 0 to 180, and eventually back, when enter is pressed on the
keyboard, flipping the pad around.
- \o \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
+ \li \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
tilt the pad vertically corresponding to which item is currently selected.
This way, the selected item is always kept in front.
- \o \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
+ \li \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
tilt the pad horizontally corresponding to which item is selected. This
way, the selected item is always kept in front.
\endlist
@@ -391,11 +391,11 @@
values when flipped back:
\list
- \o \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
- \o \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
- \o \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
- \o \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
- \o \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
+ \li \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
+ \li \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
+ \li \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
+ \li \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
+ \li \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
\endlist
All animations are given a 500 millisecond duration and an
@@ -433,10 +433,10 @@
states:
\list
- \o \c splashState: The initial state where the splash item is visible.
- \o \c frontState: The base state where the splash is gone and we can see
+ \li \c splashState: The initial state where the splash item is visible.
+ \li \c frontState: The base state where the splash is gone and we can see
the front side of the pad, and navigate the selection item.
- \o \c backState: The flipped state where the \c backItem is visible, and we
+ \li \c backState: The flipped state where the \c backItem is visible, and we
can interact with the QGraphicsProxyWidget-embedded form.
\endlist
@@ -531,18 +531,18 @@
The view toggles a few necessary properties:
\list
- \o It disables its scroll bars - this application has no use for scroll bars.
- \o It assigns a minimum size. This is necessary to avoid numerical errors
+ \li It disables its scroll bars - this application has no use for scroll bars.
+ \li It assigns a minimum size. This is necessary to avoid numerical errors
in our fit-in-view \c resizeEvent() implementation.
- \o It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
+ \li It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
ensure QGraphicsView doesn't spend time figuring out precisely what needs
to be redrawn. This application is very simple - if anything changes,
everything is updated.
- \o It enables background caching - this makes no performance difference
+ \li It enables background caching - this makes no performance difference
with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the
background pixmap.
- \o It sets render hints that increase rendering quality.
- \o If OpenGL is supported, a QGLWidget viewport is assigned to the view.
+ \li It sets render hints that increase rendering quality.
+ \li If OpenGL is supported, a QGLWidget viewport is assigned to the view.
\endlist
Finally, we start the state engine.
diff --git a/doc/src/examples/painterpaths.qdoc b/doc/src/examples/painterpaths.qdoc
index 868c4f5283..1bee28f029 100644
--- a/doc/src/examples/painterpaths.qdoc
+++ b/doc/src/examples/painterpaths.qdoc
@@ -48,9 +48,9 @@
The example consists of two classes:
\list
- \o The \c RenderArea class which is a custom widget displaying
+ \li The \c RenderArea class which is a custom widget displaying
a single painter path.
- \o The \c Window class which is the applications main window
+ \li The \c Window class which is the applications main window
displaying several \c RenderArea widgets, and allowing the user
to manipulate the painter paths' filling, pen, color
and rotation angle.
diff --git a/doc/src/examples/pixelator.qdoc b/doc/src/examples/pixelator.qdoc
index 8eec198aba..6dff9e1b87 100644
--- a/doc/src/examples/pixelator.qdoc
+++ b/doc/src/examples/pixelator.qdoc
@@ -44,9 +44,9 @@
of standard views. To do this, we implement the following components:
\list
- \i A model which represents each pixel in an image as an item of data, where each
+ \li A model which represents each pixel in an image as an item of data, where each
item contains a value for the brightness of the corresponding pixel.
- \i A custom delegate that uses the information supplied by the model to represent
+ \li A custom delegate that uses the information supplied by the model to represent
each pixel as a black circle on a white background, where the radius of the
circle corresponds to the darkness of the pixel.
\endlist
diff --git a/doc/src/examples/plugandpaint.qdoc b/doc/src/examples/plugandpaint.qdoc
index 118afa6a02..ee3f6fefe9 100644
--- a/doc/src/examples/plugandpaint.qdoc
+++ b/doc/src/examples/plugandpaint.qdoc
@@ -55,13 +55,13 @@
Plug & Paint consists of the following classes:
\list
- \o \c MainWindow is a QMainWindow subclass that provides the menu
+ \li \c MainWindow is a QMainWindow subclass that provides the menu
system and that contains a \c PaintArea as the central widget.
- \o \c PaintArea is a QWidget that allows the user to draw using a
+ \li \c PaintArea is a QWidget that allows the user to draw using a
brush and to insert shapes.
- \o \c PluginDialog is a dialog that shows information about the
+ \li \c PluginDialog is a dialog that shows information about the
plugins detected by the application.
- \o \c BrushInterface, \c ShapeInterface, and \c FilterInterface are
+ \li \c BrushInterface, \c ShapeInterface, and \c FilterInterface are
abstract base classes that can be implemented by plugins to
provide custom brushes, shapes, and image filters.
\endlist
@@ -321,10 +321,10 @@
plugin:
\list 1
- \o Declare a plugin class.
- \o Implement the interfaces provided by the plugin.
- \o Export the plugin using the Q_EXPORT_PLUGIN2() macro.
- \o Build the plugin using an adequate \c .pro file.
+ \li Declare a plugin class.
+ \li Implement the interfaces provided by the plugin.
+ \li Export the plugin using the Q_EXPORT_PLUGIN2() macro.
+ \li Build the plugin using an adequate \c .pro file.
\endlist
\section1 Declaration of the Plugin Class
@@ -377,15 +377,15 @@
Then comes the brush-dependent part of the code:
\list
- \o If the brush is \gui{Pencil}, we just call
+ \li If the brush is \gui{Pencil}, we just call
QPainter::drawLine() with the current QPen.
- \o If the brush is \gui{Air Brush}, we start by setting the
+ \li If the brush is \gui{Air Brush}, we start by setting the
painter's QBrush to Qt::Dense6Pattern to obtain a dotted
pattern. Then we draw a circle filled with that QBrush several
times, resulting in a thick line.
- \o If the brush is \gui{Random Letters}, we draw a random letter
+ \li If the brush is \gui{Random Letters}, we draw a random letter
at the new cursor position. Most of the code is for setting
the font to be bold and larger than the default font and for
computing an appropriate bounding rect.
diff --git a/doc/src/examples/rogue.qdoc b/doc/src/examples/rogue.qdoc
index 38c871c7db..44e371c667 100644
--- a/doc/src/examples/rogue.qdoc
+++ b/doc/src/examples/rogue.qdoc
@@ -64,10 +64,10 @@
The example consists of two classes:
\list
- \o \c Window draws the text display of the game and sets
+ \li \c Window draws the text display of the game and sets
up the state machine. The window also has a status bar
above the area in which the rouge moves.
- \o \c MovementTransition is a transition that carries out
+ \li \c MovementTransition is a transition that carries out
a single move of the rogue.
\endlist
diff --git a/doc/src/examples/screenshot.qdoc b/doc/src/examples/screenshot.qdoc
index e99fe6cc19..7ee7ddb9c7 100644
--- a/doc/src/examples/screenshot.qdoc
+++ b/doc/src/examples/screenshot.qdoc
@@ -41,9 +41,9 @@
desktop. They are provided with a couple of options:
\list
- \o Delaying the screenshot, giving them time to rearrange
+ \li Delaying the screenshot, giving them time to rearrange
their desktop.
- \o Hiding the application's window while the screenshot is taken.
+ \li Hiding the application's window while the screenshot is taken.
\endlist
In addition the application allows the users to save their
@@ -63,10 +63,10 @@
to facilitate the options:
\list
- \o The \c newScreenshot() slot prepares a new screenshot.
- \o The \c saveScreenshot() slot saves the last screenshot.
- \o The \c shootScreen() slot takes the screenshot.
- \o The \c updateCheckBox() slot enables or disables the
+ \li The \c newScreenshot() slot prepares a new screenshot.
+ \li The \c saveScreenshot() slot saves the last screenshot.
+ \li The \c shootScreen() slot takes the screenshot.
+ \li The \c updateCheckBox() slot enables or disables the
\gui {Hide This Window} option.
\endlist
diff --git a/doc/src/examples/scribble.qdoc b/doc/src/examples/scribble.qdoc
index d9386843a5..5d801bf9cc 100644
--- a/doc/src/examples/scribble.qdoc
+++ b/doc/src/examples/scribble.qdoc
@@ -55,9 +55,9 @@
The example consists of two classes:
\list
- \o \c ScribbleArea is a custom widget that displays a QImage and
+ \li \c ScribbleArea is a custom widget that displays a QImage and
allows to the user to draw on it.
- \o \c MainWindow provides a menu above the \c ScribbleArea.
+ \li \c MainWindow provides a menu above the \c ScribbleArea.
\endlist
We will start by reviewing the \c ScribbleArea class. Then we will
@@ -85,14 +85,14 @@
We also need the following private variables:
\list
- \o \c modified is \c true if there are unsaved
+ \li \c modified is \c true if there are unsaved
changes to the image displayed in the scribble area.
- \o \c scribbling is \c true while the user is pressing
+ \li \c scribbling is \c true while the user is pressing
the left mouse button within the scribble area.
- \o \c penWidth and \c penColor hold the currently
+ \li \c penWidth and \c penColor hold the currently
set width and color for the pen used in the application.
- \o \c image stores the image drawn by the user.
- \o \c lastPoint holds the position of the cursor at the last
+ \li \c image stores the image drawn by the user.
+ \li \c lastPoint holds the position of the cursor at the last
mouse press or mouse move event.
\endlist
@@ -176,18 +176,18 @@
good reasons for this:
\list
- \o The window system requires us to be able to redraw the widget
+ \li The window system requires us to be able to redraw the widget
\e{at any time}. For example, if the window is minimized and
restored, the window system might have forgotten the contents
of the widget and send us a paint event. In other words, we
can't rely on the window system to remember our image.
- \o Qt normally doesn't allow us to paint outside of \c
+ \li Qt normally doesn't allow us to paint outside of \c
paintEvent(). In particular, we can't paint from the mouse
event handlers. (This behavior can be changed using the
Qt::WA_PaintOnScreen widget attribute, though.)
- \o If initialized properly, a QImage is guaranteed to use 8-bit
+ \li If initialized properly, a QImage is guaranteed to use 8-bit
for each color channel (red, green, blue, and alpha), whereas
a QWidget might have a lower color depth, depending on the
monitor configuration. This means that if we load a 24-bit or
diff --git a/doc/src/examples/simpletreemodel.qdoc b/doc/src/examples/simpletreemodel.qdoc
index 36e0632eb2..ed584a3307 100644
--- a/doc/src/examples/simpletreemodel.qdoc
+++ b/doc/src/examples/simpletreemodel.qdoc
@@ -59,8 +59,8 @@
\target SimpleTreeModelStructure
\table
- \row \i \inlineimage treemodel-structure.png
- \i \bold{Simple Tree Model Structure}
+ \row \li \inlineimage treemodel-structure.png
+ \li \b{Simple Tree Model Structure}
The data is stored internally in the model using \c TreeItem objects that
are linked together in a pointer-based tree structure. Generally, each
@@ -101,14 +101,14 @@
structure. The functions provide the following features:
\list
- \o The \c appendChildItem() is used to add data when the model is first
+ \li The \c appendChildItem() is used to add data when the model is first
constructed and is not used during normal use.
- \o The \c child() and \c childCount() functions allow the model to obtain
+ \li The \c child() and \c childCount() functions allow the model to obtain
information about any child items.
- \o Information about the number of columns associated with the item is
+ \li Information about the number of columns associated with the item is
provided by \c columnCount(), and the data in each column can be
obtained with the data() function.
- \o The \c row() and \c parent() functions are used to obtain the item's
+ \li The \c row() and \c parent() functions are used to obtain the item's
row number and parent item.
\endlist
@@ -320,10 +320,10 @@
We process the text file with the following two rules:
\list
- \o For each pair of strings on each line, create an item (or node)
+ \li For each pair of strings on each line, create an item (or node)
in a tree structure, and place each string in a column of data
in the item.
- \o When the first string on a line is indented with respect to the
+ \li When the first string on a line is indented with respect to the
first string on the previous line, make the item a child of the
previous item created.
\endlist
diff --git a/doc/src/examples/sipdialog.qdoc b/doc/src/examples/sipdialog.qdoc
index 2b51af4fdc..b5f18cb4be 100644
--- a/doc/src/examples/sipdialog.qdoc
+++ b/doc/src/examples/sipdialog.qdoc
@@ -34,8 +34,8 @@
the Windows Mobile SIP (Software Input Panel) and reacts to it.
\table
- \row \o \inlineimage sipdialog-closed.png
- \o \inlineimage sipdialog-opened.png
+ \row \li \inlineimage sipdialog-closed.png
+ \li \inlineimage sipdialog-opened.png
\endtable
Sometimes it is necessary for a dialog to take the SIP into account,
@@ -90,10 +90,10 @@
The following signals are connected to their respective slots:
\list
- \o \c{button}'s \l{QPushButton::pressed()}{pressed()} signal to
+ \li \c{button}'s \l{QPushButton::pressed()}{pressed()} signal to
\l{QApplication}'s \l{QApplication::closeAllWindows()}
{closeAllWindows()} slot,
- \o \l{QDesktopWidget}'s \l{QDesktopWidget::workAreaResized()}
+ \li \l{QDesktopWidget}'s \l{QDesktopWidget::workAreaResized()}
{workAreaResized()} signal to \c{dialog}'s \c desktopResized() slot.
\endlist
diff --git a/doc/src/examples/sliders.qdoc b/doc/src/examples/sliders.qdoc
index e71986bfc9..49d41a9d18 100644
--- a/doc/src/examples/sliders.qdoc
+++ b/doc/src/examples/sliders.qdoc
@@ -46,10 +46,10 @@
\list
- \o \c SlidersGroup is a custom widget. It combines a QSlider, a
+ \li \c SlidersGroup is a custom widget. It combines a QSlider, a
QScrollBar and a QDial.
- \o \c Window is the main widget combining a QGroupBox and a
+ \li \c Window is the main widget combining a QGroupBox and a
QStackedWidget. In this example, the QStackedWidget provides a
stack of two \c SlidersGroup widgets. The QGroupBox contain
several widgets that control the behavior of the slider-like
@@ -122,10 +122,10 @@
slider-like widgets:
\table
- \header \o \o{2,1} QSlider \o{2,1} QScrollBar \o{2,1} QDial
- \header \o \o Normal \o Inverted \o Normal \o Inverted \o Normal \o Inverted
- \row \o Qt::Horizontal \o Left to right \o Right to left \o Left to right \o Right to left \o Clockwise \o Counterclockwise
- \row \o Qt::Vertical \o Bottom to top \o Top to bottom \o Top to bottom \o Bottom to top \o Clockwise \o Counterclockwise
+ \header \li \li{2,1} QSlider \li{2,1} QScrollBar \li{2,1} QDial
+ \header \li \li Normal \li Inverted \li Normal \li Inverted \li Normal \li Inverted
+ \row \li Qt::Horizontal \li Left to right \li Right to left \li Left to right \li Right to left \li Clockwise \li Counterclockwise
+ \row \li Qt::Vertical \li Bottom to top \li Top to bottom \li Top to bottom \li Bottom to top \li Clockwise \li Counterclockwise
\endtable
It is common to invert the appearance of a vertical QSlider. A
diff --git a/doc/src/examples/stardelegate.qdoc b/doc/src/examples/stardelegate.qdoc
index 01507eaf82..c9cc1f40cf 100644
--- a/doc/src/examples/stardelegate.qdoc
+++ b/doc/src/examples/stardelegate.qdoc
@@ -58,15 +58,15 @@
The example consists of the following classes:
\list
- \o \c StarRating is the custom data type. It stores a rating
+ \li \c StarRating is the custom data type. It stores a rating
expressed as stars, such as "2 out of 5 stars" or "5 out of
6 stars".
- \o \c StarDelegate inherits QItemDelegate and provides support
+ \li \c StarDelegate inherits QItemDelegate and provides support
for \c StarRating (in addition to the data types already
handled by QItemDelegate).
- \o \c StarEditor inherits QWidget and is used by \c StarDelegate
+ \li \c StarEditor inherits QWidget and is used by \c StarDelegate
to let the user edit a star rating using the mouse.
\endlist
@@ -281,7 +281,7 @@
editor are:
\list
- \o It is possible to open editors programmatically by calling
+ \li It is possible to open editors programmatically by calling
QAbstractItemView::edit(), instead of relying on edit
triggers. This could be use to support other edit triggers
than those offered by the QAbstractItemView::EditTrigger enum.
@@ -289,7 +289,7 @@
item with the mouse might make sense as a way to pop up an
editor.
- \o By reimplementing QAbstractItemDelegate::editorEvent(), it is
+ \li By reimplementing QAbstractItemDelegate::editorEvent(), it is
possible to implement the editor directly in the delegate,
instead of creating a separate QWidget subclass.
\endlist
diff --git a/doc/src/examples/styles.qdoc b/doc/src/examples/styles.qdoc
index 91fd1d54d7..d1f5091a4b 100644
--- a/doc/src/examples/styles.qdoc
+++ b/doc/src/examples/styles.qdoc
@@ -56,9 +56,9 @@
The example consists of the following classes:
\list
- \o \c NorwegianWoodStyle inherits from QMotifStyle and implements
+ \li \c NorwegianWoodStyle inherits from QMotifStyle and implements
the Norwegian Wood style.
- \o \c WidgetGallery is a \c QDialog subclass that shows the most
+ \li \c WidgetGallery is a \c QDialog subclass that shows the most
common widgets and allows the user to switch style
dynamically.
\endlist
@@ -91,16 +91,16 @@
resources}.
\table
- \row \o \inlineimage widgets/styles/images/woodbackground.png
+ \row \li \inlineimage widgets/styles/images/woodbackground.png
- \o \bold{woodbackground.png}
+ \li \b{woodbackground.png}
This texture is used as the background of most widgets.
The wood pattern is horizontal.
- \row \o \inlineimage widgets/styles/images/woodbutton.png
+ \row \li \inlineimage widgets/styles/images/woodbutton.png
- \o \bold{woodbutton.png}
+ \li \b{woodbutton.png}
This texture is used for filling push buttons and
comboboxes. The wood pattern is vertical and more reddish
@@ -261,17 +261,17 @@
them based on the state of the button:
\list
- \o If the button is a \l{QPushButton::flat}{flat button}, we use
+ \li If the button is a \l{QPushButton::flat}{flat button}, we use
the \l{QPalette::Background}{Background} brush. We set \c
darker to \c true if the button is
\l{QAbstractButton::down}{down} or
\l{QAbstractButton::checked}{checked}.
- \o If the button is currently held down by the user or in the
+ \li If the button is currently held down by the user or in the
\l{QAbstractButton::checked}{checked} state, we use the
\l{QPalette::Mid}{Mid} component of the palette. We set
\c darker to \c true if the button is
\l{QAbstractButton::checked}{checked}.
- \o Otherwise, we use the \l{QPalette::Button}{Button} component
+ \li Otherwise, we use the \l{QPalette::Button}{Button} component
of the palette.
\endlist
diff --git a/doc/src/examples/svgalib.qdoc b/doc/src/examples/svgalib.qdoc
index cac14a7469..f25a3e21a8 100644
--- a/doc/src/examples/svgalib.qdoc
+++ b/doc/src/examples/svgalib.qdoc
@@ -49,13 +49,13 @@
approach:
\list 1
- \o \l {Step 1: Creating a Custom Graphics Driver}
+ \li \l {Step 1: Creating a Custom Graphics Driver}
{Creating a Custom Graphics Driver}
- \o \l {Step 2: Implementing a Custom Raster Paint Engine}
+ \li \l {Step 2: Implementing a Custom Raster Paint Engine}
{Implementing a Custom Paint Engine}
- \o \l {Step 3: Making the Widgets Aware of the Custom Paint
+ \li \l {Step 3: Making the Widgets Aware of the Custom Paint
Engine}{Making the Widgets Aware of the Custom Paint Engine}
\endlist
@@ -69,8 +69,8 @@
\snippet doc/src/snippets/code/doc_src_examples_svgalib.qdoc 0
\table
- \header \o SVGAlib
- \row \o
+ \header \li SVGAlib
+ \row \li
Instead of interfacing the graphics hardware directly, this
example relies on \l {http://www.svgalib.org}{SVGAlib} being
@@ -212,9 +212,9 @@
respectively.
\table
- \header \o Private Header Files
+ \header \li Private Header Files
\row
- \o
+ \li
Note the \c include statement used by this class. The files
prefixed with \c private/ are private headers file within
@@ -285,9 +285,9 @@
adjustments of the graphics driver.
\list
- \o \l {Implementing a Custom Paint Device}
- \o \l {Implementing a Custom Window Surface}
- \o \l {Adjusting the Graphics Driver}
+ \li \l {Implementing a Custom Paint Device}
+ \li \l {Implementing a Custom Window Surface}
+ \li \l {Adjusting the Graphics Driver}
\endlist
\section2 Implementing a Custom Paint Device
diff --git a/doc/src/examples/syntaxhighlighter.qdoc b/doc/src/examples/syntaxhighlighter.qdoc
index d86719ab19..597a1a2bf3 100644
--- a/doc/src/examples/syntaxhighlighter.qdoc
+++ b/doc/src/examples/syntaxhighlighter.qdoc
@@ -40,9 +40,9 @@
The example consists of two classes:
\list
- \o The \c Highlighter class defines and applies the
+ \li The \c Highlighter class defines and applies the
highlighting rules.
- \o The \c MainWindow widget is the application's main window.
+ \li The \c MainWindow widget is the application's main window.
\endlist
We will first review the \c Highlighter class to see how you can
diff --git a/doc/src/examples/tablet.qdoc b/doc/src/examples/tablet.qdoc
index 249b593e9b..57fa7d5eca 100644
--- a/doc/src/examples/tablet.qdoc
+++ b/doc/src/examples/tablet.qdoc
@@ -61,15 +61,15 @@
The example consists of the following:
\list
- \o The \c MainWindow class inherits QMainWindow and creates
+ \li The \c MainWindow class inherits QMainWindow and creates
the examples menus and connect their slots and signals.
- \o The \c TabletCanvas class inherits QWidget and
+ \li The \c TabletCanvas class inherits QWidget and
receives tablet events. It uses the events to paint on a
offscreen pixmap, which it draws onto itself.
- \o The \c TabletApplication class inherits QApplication. This
+ \li The \c TabletApplication class inherits QApplication. This
class handles tablet events that are not sent to \c tabletEvent().
We will look at this later.
- \o The \c main() function creates a \c MainWindow and shows it
+ \li The \c main() function creates a \c MainWindow and shows it
as a top level window.
\endlist
diff --git a/doc/src/examples/tetrix.qdoc b/doc/src/examples/tetrix.qdoc
index 1eb92a2a4a..fca5229ad8 100644
--- a/doc/src/examples/tetrix.qdoc
+++ b/doc/src/examples/tetrix.qdoc
@@ -53,11 +53,11 @@
This example shows how a simple game can be created using only three classes:
\list
- \o The \c TetrixWindow class is used to display the player's score, number of
+ \li The \c TetrixWindow class is used to display the player's score, number of
lives, and information about the next piece to appear.
- \o The \c TetrixBoard class contains the game logic, handles keyboard input, and
+ \li The \c TetrixBoard class contains the game logic, handles keyboard input, and
displays the pieces on the playing area.
- \o The \c TetrixPiece class contains information about each piece.
+ \li The \c TetrixPiece class contains information about each piece.
\endlist
In this approach, the \c TetrixBoard class is the most complex class, since it
diff --git a/doc/src/examples/textfinder.qdoc b/doc/src/examples/textfinder.qdoc
index 17c52c2208..8f1ed5d340 100644
--- a/doc/src/examples/textfinder.qdoc
+++ b/doc/src/examples/textfinder.qdoc
@@ -37,16 +37,16 @@
resource and is loaded into the display at startup.
\table
- \row \o \inlineimage textfinder-example-find.png
- \o \inlineimage textfinder-example-find2.png
+ \row \li \inlineimage textfinder-example-find.png
+ \li \inlineimage textfinder-example-find2.png
\endtable
\section1 Setting Up The Resource File
The resources required for Text Finder are:
\list
- \o \e{textfinder.ui} - the user interface file created in QtDesigner
- \o \e{input.txt} - a text file containing some text to be displayed
+ \li \e{textfinder.ui} - the user interface file created in QtDesigner
+ \li \e{input.txt} - a text file containing some text to be displayed
in the QTextEdit
\endlist
diff --git a/doc/src/examples/tooltips.qdoc b/doc/src/examples/tooltips.qdoc
index d506268bd8..cfa1884097 100644
--- a/doc/src/examples/tooltips.qdoc
+++ b/doc/src/examples/tooltips.qdoc
@@ -53,8 +53,8 @@
The Tooltips example consists of two classes:
\list
- \o \c ShapeItem is a custom widget representing one single shape item.
- \o \c SortingBox inherits from QWidget and is the application's main
+ \li \c ShapeItem is a custom widget representing one single shape item.
+ \li \c SortingBox inherits from QWidget and is the application's main
widget.
\endlist
diff --git a/doc/src/examples/transformations.qdoc b/doc/src/examples/transformations.qdoc
index 9a23c6c8e6..8bca26eb77 100644
--- a/doc/src/examples/transformations.qdoc
+++ b/doc/src/examples/transformations.qdoc
@@ -42,9 +42,9 @@
The example consists of two classes and a global enum:
\list
- \o The \c RenderArea class controls the rendering of a given shape.
- \o The \c Window class is the application's main window.
- \o The \c Operation enum describes the various transformation
+ \li The \c RenderArea class controls the rendering of a given shape.
+ \li The \c Window class is the application's main window.
+ \li The \c Operation enum describes the various transformation
operations available in the application.
\endlist
diff --git a/doc/src/examples/trollprint.qdoc b/doc/src/examples/trollprint.qdoc
index 4127348b39..63566bdc21 100644
--- a/doc/src/examples/trollprint.qdoc
+++ b/doc/src/examples/trollprint.qdoc
@@ -200,11 +200,11 @@
editor and follow these steps:
\list
- \o Uncomment the two lines that create a QLabel with the text
+ \li Uncomment the two lines that create a QLabel with the text
"\<b\>TROLL PRINT\</b\>" in \c printpanel.cpp.
- \o Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp.
- \o Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp.
- \o Update the copyright year to 1999-2000 in \c mainwindow.cpp.
+ \li Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp.
+ \li Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp.
+ \li Update the copyright year to 1999-2000 in \c mainwindow.cpp.
\endlist
(Of course the version number and copyright year would be consts or
@@ -214,25 +214,25 @@
Linguist}. The following items are of special interest:
\list
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o Troll Print 1.0 - marked "(obs.)", obsolete
- \o About Troll Print 1.0 - marked "(obs.)", obsolete
- \o Troll Print 1.0. Copyright 1999 Software, Inc. -
+ \li Troll Print 1.0 - marked "(obs.)", obsolete
+ \li About Troll Print 1.0 - marked "(obs.)", obsolete
+ \li Troll Print 1.0. Copyright 1999 Software, Inc. -
marked obsolete
- \o Troll Print 1.1 - automatically translated as
+ \li Troll Print 1.1 - automatically translated as
"Troll Imprimir 1.1"
- \o About Troll Print 1.1 - automatically translated as
+ \li About Troll Print 1.1 - automatically translated as
"Troll Imprimir 1.1"
- \o Troll Print 1.1. Copyright 1999-2000 Software,
+ \li Troll Print 1.1. Copyright 1999-2000 Software,
Inc. - automatically translated as "Troll Imprimir 1.1.
Copyright 1999-2000 Software, Inc."
\endlist
- \o \c PrintPanel
+ \li \c PrintPanel
\list
- \o 2-sided - marked "(obs.)", obsolete
- \o \<b\>TROLL PRINT\</b\> - unmarked, i.e. untranslated
- \o Two-sided - unmarked, i.e. untranslated.
+ \li 2-sided - marked "(obs.)", obsolete
+ \li \<b\>TROLL PRINT\</b\> - unmarked, i.e. untranslated
+ \li Two-sided - unmarked, i.e. untranslated.
\endlist
\endlist
diff --git a/doc/src/examples/undoframework.qdoc b/doc/src/examples/undoframework.qdoc
index 36e43f2ed8..0bc2efd025 100644
--- a/doc/src/examples/undoframework.qdoc
+++ b/doc/src/examples/undoframework.qdoc
@@ -61,18 +61,18 @@
The example consists of the following classes:
\list
- \o \c MainWindow is the main window and arranges the
+ \li \c MainWindow is the main window and arranges the
example's widgets. It creates the commands based
on user input and keeps them on the command stack.
- \o \c AddCommand adds an item to the scene.
- \o \c DeleteCommand deletes an item from the scene.
- \o \c MoveCommand when an item is moved the MoveCommand keeps record
+ \li \c AddCommand adds an item to the scene.
+ \li \c DeleteCommand deletes an item from the scene.
+ \li \c MoveCommand when an item is moved the MoveCommand keeps record
of the start and stop positions of the move, and it
moves the item according to these when \c redo() and \c undo()
is called.
- \o \c DiagramScene inherits QGraphicsScene and
+ \li \c DiagramScene inherits QGraphicsScene and
emits signals for the \c MoveComands when an item is moved.
- \o \c DiagramItem inherits QGraphicsPolygonItem and represents
+ \li \c DiagramItem inherits QGraphicsPolygonItem and represents
an item in the diagram.
\endlist
diff --git a/doc/src/examples/wiggly.qdoc b/doc/src/examples/wiggly.qdoc
index 739f14d623..677e8b08ca 100644
--- a/doc/src/examples/wiggly.qdoc
+++ b/doc/src/examples/wiggly.qdoc
@@ -48,10 +48,10 @@
The example consists of two classes:
\list
- \o \c WigglyWidget is the custom widget displaying the text
+ \li \c WigglyWidget is the custom widget displaying the text
in a wiggly line.
- \o \c Dialog is the dialog widget allowing the user to enter a
+ \li \c Dialog is the dialog widget allowing the user to enter a
text. It combines a \c WigglyWidget and a \c QLineEdit.
\endlist
diff --git a/doc/src/examples/windowflags.qdoc b/doc/src/examples/windowflags.qdoc
index e39e4eddc7..09dc45c27f 100644
--- a/doc/src/examples/windowflags.qdoc
+++ b/doc/src/examples/windowflags.qdoc
@@ -46,10 +46,10 @@
The example consists of two classes:
\list
- \o \c ControllerWindow is the main application widget that allows
+ \li \c ControllerWindow is the main application widget that allows
the user to choose among the available window flags, and displays
the effect on a separate preview window.
- \o \c PreviewWindow is a custom widget displaying the name of
+ \li \c PreviewWindow is a custom widget displaying the name of
its currently set window flags in a read-only text editor.
\endlist
diff --git a/doc/src/gui/coordsys.qdoc b/doc/src/gui/coordsys.qdoc
index ae1506ddd8..655dbf7cf3 100644
--- a/doc/src/gui/coordsys.qdoc
+++ b/doc/src/gui/coordsys.qdoc
@@ -67,11 +67,11 @@
\table
\row
- \o \inlineimage coordinatesystem-rect.png
- \o \inlineimage coordinatesystem-line.png
+ \li \inlineimage coordinatesystem-rect.png
+ \li \inlineimage coordinatesystem-line.png
\row
- \o QRect(1, 2, 6, 4)
- \o QLine(2, 7, 6, 1)
+ \li QRect(1, 2, 6, 4)
+ \li QLine(2, 7, 6, 1)
\endtable
\section2 Aliased Painting
@@ -92,14 +92,14 @@
\table
\row
- \o \inlineimage coordinatesystem-rect-raster.png
- \o \inlineimage coordinatesystem-line-raster.png
+ \li \inlineimage coordinatesystem-rect-raster.png
+ \li \inlineimage coordinatesystem-line-raster.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 0
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 1
\endtable
@@ -112,19 +112,19 @@
\table
\header
- \o {3,1} QRectF
+ \li {3,1} QRectF
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrectf-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrectf-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrectf-diagram-two.png
- \o \inlineimage qrectf-diagram-three.png
+ \li \inlineimage qrectf-diagram-two.png
+ \li \inlineimage qrectf-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
Note that for historical reasons the return value of the
@@ -158,14 +158,14 @@
\table
\row
- \o \inlineimage coordinatesystem-rect-antialias.png
- \o \inlineimage coordinatesystem-line-antialias.png
+ \li \inlineimage coordinatesystem-rect-antialias.png
+ \li \inlineimage coordinatesystem-line-antialias.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 2
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 3
\endtable
@@ -183,15 +183,15 @@
\table
\row
- \o \inlineimage qpainter-clock.png
- \o \inlineimage qpainter-rotation.png
- \o \inlineimage qpainter-scale.png
- \o \inlineimage qpainter-translation.png
+ \li \inlineimage qpainter-clock.png
+ \li \inlineimage qpainter-rotation.png
+ \li \inlineimage qpainter-scale.png
+ \li \inlineimage qpainter-translation.png
\row
- \o nop
- \o \l {QPainter::rotate()}{rotate()}
- \o \l {QPainter::scale()}{scale()}
- \o \l {QPainter::translate()}{translate()}
+ \li nop
+ \li \l {QPainter::rotate()}{rotate()}
+ \li \l {QPainter::scale()}{scale()}
+ \li \l {QPainter::translate()}{translate()}
\endtable
You can also twist the coordinate system around the origin using
@@ -218,10 +218,10 @@
\table 100%
\header
- \o {2,1} Analog Clock Example
+ \li {2,1} Analog Clock Example
\row
- \o \inlineimage coordinatesystem-analogclock.png
- \o
+ \li \inlineimage coordinatesystem-analogclock.png
+ \li
The Analog Clock example shows how to draw the contents of a
custom widget using QPainter's transformation matrix.
@@ -236,7 +236,7 @@
sizes.
\row
- \o {2,1}
+ \li {2,1}
\snippet examples/widgets/analogclock/analogclock.cpp 9
@@ -368,23 +368,23 @@
QPaintDevice, and QPaintEngine classes:
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o QPainter
- \o
+ \li QPainter
+ \li
The QPainter class performs low-level painting on widgets and
other paint devices. QPainter can operate on any object that
inherits the QPaintDevice class, using the same code.
\row
- \o QPaintDevice
- \o
+ \li QPaintDevice
+ \li
The QPaintDevice class is the base class of objects that can be
painted. Qt provides several devices: QWidget, QImage, QPixmap,
QPrinter and QPicture, and other devices can also be defined by
subclassing QPaintDevice.
\row
- \o QPaintEngine
- \o
+ \li QPaintEngine
+ \li
The QPaintEngine class provides an abstract definition of how
QPainter draws to a given device on a given platform. Qt 4
provides several premade implementations of QPaintEngine for the
@@ -397,10 +397,10 @@
using the QTransform class:
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o QTransform
- \o
+ \li QTransform
+ \li
A 3 x 3 transformation matrix. Use QTransform to rotate, shear,
scale, or translate the coordinate system.
\endtable
@@ -411,45 +411,45 @@
name is suffixed with an \c F.
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o \l{QPoint}(\l{QPointF}{F})
- \o
+ \li \l{QPoint}(\l{QPointF}{F})
+ \li
A single 2D point in the coordinate system. Most functions in Qt
that deal with points can accept either a QPoint, a QPointF, two
\c{int}s, or two \c{qreal}s.
\row
- \o \l{QSize}(\l{QSizeF}{F})
- \o
+ \li \l{QSize}(\l{QSizeF}{F})
+ \li
A single 2D vector. Internally, QPoint and QSize are the same, but
a point is not the same as a size, so both classes exist. Again,
most functions accept either QSizeF, a QSize, two \c{int}s, or two
\c{qreal}s.
\row
- \o \l{QRect}(\l{QRectF}{F})
- \o
+ \li \l{QRect}(\l{QRectF}{F})
+ \li
A 2D rectangle. Most functions accept either a QRectF, a QRect,
four \c{int}s, or four \c {qreal}s.
\row
- \o \l{QLine}(\l{QLineF}{F})
- \o
+ \li \l{QLine}(\l{QLineF}{F})
+ \li
A 2D finite-length line, characterized by a start point and an end
point.
\row
- \o \l{QPolygon}(\l{QPolygonF}{F})
- \o
+ \li \l{QPolygon}(\l{QPolygonF}{F})
+ \li
A 2D polygon. A polygon is a vector of \c{QPoint(F)}s. If the
first and last points are the same, the polygon is closed.
\row
- \o QPainterPath
- \o
+ \li QPainterPath
+ \li
A vectorial specification of a 2D shape. Painter paths are the
ultimate painting primitive, in the sense that any shape
(rectange, ellipse, spline) or combination of shapes can be
expressed as a path. A path specifies both an outline and an area.
\row
- \o QRegion
- \o
+ \li QRegion
+ \li
An area in a paint device, expressed as a list of
\l{QRect}s. In general, we recommend using the vectorial
QPainterPath class instead of QRegion for specifying areas,
diff --git a/doc/src/gui/paintsystem.qdoc b/doc/src/gui/paintsystem.qdoc
index f9670ff5d8..4b33e4fed3 100644
--- a/doc/src/gui/paintsystem.qdoc
+++ b/doc/src/gui/paintsystem.qdoc
@@ -74,13 +74,13 @@
\section1 Topics
\list
- \o \l{Classes for Painting}
- \o \l{Paint Devices and Backends}
- \o \l{Drawing and Filling}
- \o \l{Coordinate System}
- \o \l{Reading and Writing Image Files}
- \o \l{Styling}
- \o \l{Printing with Qt}
+ \li \l{Classes for Painting}
+ \li \l{Paint Devices and Backends}
+ \li \l{Drawing and Filling}
+ \li \l{Coordinate System}
+ \li \l{Reading and Writing Image Files}
+ \li \l{Styling}
+ \li \l{Printing with Qt}
\endlist
\section1 Classes for Painting
@@ -115,14 +115,14 @@
\image paintsystem-devices.png
\table 100%
- \row \o \bold Widget
+ \row \li \b Widget
The QWidget class is the base class of all user interface
objects. The widget is the atom of the user interface: it receives
mouse, keyboard and other events from the window system, and
paints a representation of itself on the screen.
- \row \o \bold Image
+ \row \li \b Image
The QImage class provides a hardware-independent image
representation which is designed and optimized for I/O, and for
@@ -136,7 +136,7 @@
painting can be performed in another thread than the current GUI
thread.
- \row \o \bold Pixmap
+ \row \li \b Pixmap
The QPixmap class is an off-screen image representation which is
designed and optimized for showing images on screen. Unlike
@@ -156,7 +156,7 @@
constructing QRegion objects, and for setting masks for pixmaps
and widgets.
- \row \o \bold {OpenGL Widget}
+ \row \li \b {OpenGL Widget}
As mentioned previously, Qt provides the QtOpenGL module offering
classes that makes it easy to use OpenGL in Qt applications. For
@@ -169,7 +169,7 @@
most drawing operations, such as transformations and pixmap
drawing.
- \row \o \bold {Pixel Buffer}
+ \row \li \b {Pixel Buffer}
The QtOpenGL module also provides the QGLPixelBuffer class which
inherits QPaintDevice directly.
@@ -178,7 +178,7 @@
pbuffer is normally done using full hardware acceleration which
can be significantly faster than rendering into a QPixmap.
- \row \o \bold {Framebuffer Object}
+ \row \li \b {Framebuffer Object}
The QtOpenGL module also provides the QGLFramebufferObject class
which inherits QPaintDevice directly.
@@ -188,7 +188,7 @@
offer several advantages over pixel buffers for this purpose.
These are described in the QGLFramebufferObject class documentation.
- \row \o \bold {Picture}
+ \row \li \b {Picture}
The QPicture class is a paint device that records and replays
QPainter commands. A picture serializes painter commands to an IO
@@ -200,7 +200,7 @@
Qt provides the QPicture::load() and QPicture::save() functions
as well as streaming operators for loading and saving pictures.
- \row \o \bold {Printer}
+ \row \li \b {Printer}
The QPrinter class is a paint device that paints on a printer. On
Windows or Mac OS X, QPrinter uses the built-in printer
@@ -218,7 +218,7 @@
to QPrinter::PdfFormat, QPrinter will generate its output as a PDF
file.
- \row \o \bold {Custom Backends}
+ \row \li \b {Custom Backends}
Support for a new backend can be implemented by deriving from the
QPaintDevice class and reimplementing the virtual
@@ -238,17 +238,17 @@
\table
\row
- \o Windows
- \o Software Rasterizer
+ \li Windows
+ \li Software Rasterizer
\row
- \o X11
- \o X11
+ \li X11
+ \li X11
\row
- \o Mac OS X
- \o CoreGraphics
+ \li Mac OS X
+ \li CoreGraphics
\row
- \o Embedded
- \o Software Rasterizer
+ \li Embedded
+ \li Software Rasterizer
\endtable
Passing a command line parameter to the application, such as,
@@ -289,8 +289,8 @@
\table 100%
\row
- \o \image paintsystem-painterpath.png
- \o \bold QPainterPath
+ \li \image paintsystem-painterpath.png
+ \li \b QPainterPath
A painter path is an object composed of lines and curves. For
example, a rectangle is composed by lines and an ellipse is
@@ -333,8 +333,8 @@
pixels, and the benefits of anti-aliased painting.
\table 100%
- \row \o
- \bold {Anti-Aliased Painting}
+ \row \li
+ \b {Anti-Aliased Painting}
When drawing, the pixel rendering is controlled by the
QPainter::Antialiasing render hint. The QPainter::RenderHint enum
@@ -345,7 +345,7 @@
antialias edges of primitives if possible, i.e. smoothing the
edges by using different color intensities.
- \o \image paintsystem-antialiasing.png
+ \li \image paintsystem-antialiasing.png
\endtable
@@ -376,8 +376,8 @@
\table 100%
\row
- \o \image paintsystem-fancygradient.png
- \o \bold QGradient
+ \li \image paintsystem-fancygradient.png
+ \li \b QGradient
The QGradient class is used in combination with QBrush to specify
gradient fills.
@@ -416,14 +416,14 @@
\table 100%
\row
- \o \bold QMovie
+ \li \b QMovie
QMovie is a convenience class for displaying animations, using the
QImageReader class internally. Once created, the QMovie class
provides various functions for both running and controlling the
given animation.
- \o \image paintsystem-movie.png
+ \li \image paintsystem-movie.png
\endtable
The QImageReader and QImageWriter classes rely on the
@@ -450,8 +450,8 @@
\table 100%
\row
- \o \image paintsystem-svg.png
- \o \bold {SVG Rendering}
+ \li \image paintsystem-svg.png
+ \li \b {SVG Rendering}
Scalable Vector Graphics (SVG) is a language for describing two-dimensional
graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation
@@ -513,10 +513,10 @@
Most functions for drawing style elements take four arguments:
\list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption object specifying how and where to render that element
- \o a QPainter object that should be used to draw the element
- \o a QWidget object on which the drawing is performed (optional)
+ \li an enum value specifying which graphical element to draw
+ \li a QStyleOption object specifying how and where to render that element
+ \li a QPainter object that should be used to draw the element
+ \li a QWidget object on which the drawing is performed (optional)
\endlist
The style gets all the information it needs to render the
@@ -538,8 +538,8 @@
\table 100%
\row
- \o \inlineimage paintsystem-icon.png
- \o \bold QIcon
+ \li \inlineimage paintsystem-icon.png
+ \li \b QIcon
The QIcon class provides scalable icons in different modes and states.
diff --git a/doc/src/network/files-and-resources/datastreamformat.qdoc b/doc/src/network/files-and-resources/datastreamformat.qdoc
index 97cadac93e..17a0044a69 100644
--- a/doc/src/network/files-and-resources/datastreamformat.qdoc
+++ b/doc/src/network/files-and-resources/datastreamformat.qdoc
@@ -43,326 +43,326 @@
the application happens to be running on.
\table
- \row \o bool
- \o \list
- \o boolean
- \endlist
- \row \o qint8
- \o \list
- \o signed byte
- \endlist
- \row \o qint16
- \o \list
- \o signed 16-bit integer
- \endlist
- \row \o qint32
- \o \list
- \o signed 32-bit integer
- \endlist
- \row \o qint64
- \o \list
- \o signed 64-bit integer
- \endlist
- \row \o quint8
- \o \list
- \o unsigned byte
- \endlist
- \row \o quint16
- \o \list
- \o unsigned 16-bit integer
- \endlist
- \row \o quint32
- \o \list
- \o unsigned 32-bit integer
- \endlist
- \row \o quint64
- \o \list
- \o unsigned 64-bit integer
- \endlist
- \row \o \c float
- \o \list
- \o 32-bit floating point number using the standard IEEE 754 format
- \endlist
- \row \o \c double
- \o \list
- \o 64-bit floating point number using the standard IEEE 754 format
- \endlist
- \row \o \c {const char *}
- \o \list
- \o The string length (quint32)
- \o The string bytes, excluding the terminating 0
- \endlist
- \row \o QBitArray
- \o \list
- \o The array size (quint32)
- \o The array bits, i.e. (size + 7)/8 bytes
- \endlist
- \row \o QBrush
- \o \list
- \o The brush style (quint8)
- \o The brush color (QColor)
- \o If style is CustomPattern, the brush pixmap (QPixmap)
- \endlist
- \row \o QByteArray
- \o \list
- \o If the byte array is null: 0xFFFFFFFF (quint32)
- \o Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
- \endlist
- \row \o \l QColor
- \o \list
- \o Color spec (qint8)
- \o Alpha value (quint16)
- \o Red value (quint16)
- \o Green value (quint16)
- \o Blue value (quint16)
- \o Pad value (quint16)
- \endlist
- \row \o QCursor
- \o \list
- \o Shape ID (qint16)
- \o If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
- \endlist
- \row \o QDate
- \o \list
- \o Julian day (quint32)
- \endlist
- \row \o QDateTime
- \o \list
- \o Date (QDate)
- \o Time (QTime)
- \o 0 for Qt::LocalTime, 1 for Qt::UTC (quint8)
- \endlist
- \row \o QEasingCurve
- \o \list
- \o type (quint8)
- \o func (quint64)
- \o hasConfig (bool)
- \o If hasConfig is true then these fields follow:
- \o list
- \o period (double)
- \o amplitude (double)
- \o overshoot (double)
- \endlist
- \row \o QFont
- \o \list
- \o The family (QString)
- \o The point size (qint16)
- \o The style hint (quint8)
- \o The char set (quint8)
- \o The weight (quint8)
- \o The font bits (quint8)
- \endlist
- \row \o QHash<Key, T>
- \o \list
- \o The number of items (quint32)
- \o For all items, the key (Key) and value (T)
- \endlist
- \row \o QIcon
- \o \list
- \o The number of pixmap entries (quint32)
- \o For all pixmap entries:
+ \row \li bool
+ \li \list
+ \li boolean
+ \endlist
+ \row \li qint8
+ \li \list
+ \li signed byte
+ \endlist
+ \row \li qint16
+ \li \list
+ \li signed 16-bit integer
+ \endlist
+ \row \li qint32
+ \li \list
+ \li signed 32-bit integer
+ \endlist
+ \row \li qint64
+ \li \list
+ \li signed 64-bit integer
+ \endlist
+ \row \li quint8
+ \li \list
+ \li unsigned byte
+ \endlist
+ \row \li quint16
+ \li \list
+ \li unsigned 16-bit integer
+ \endlist
+ \row \li quint32
+ \li \list
+ \li unsigned 32-bit integer
+ \endlist
+ \row \li quint64
+ \li \list
+ \li unsigned 64-bit integer
+ \endlist
+ \row \li \c float
+ \li \list
+ \li 32-bit floating point number using the standard IEEE 754 format
+ \endlist
+ \row \li \c double
+ \li \list
+ \li 64-bit floating point number using the standard IEEE 754 format
+ \endlist
+ \row \li \c {const char *}
+ \li \list
+ \li The string length (quint32)
+ \li The string bytes, excluding the terminating 0
+ \endlist
+ \row \li QBitArray
+ \li \list
+ \li The array size (quint32)
+ \li The array bits, i.e. (size + 7)/8 bytes
+ \endlist
+ \row \li QBrush
+ \li \list
+ \li The brush style (quint8)
+ \li The brush color (QColor)
+ \li If style is CustomPattern, the brush pixmap (QPixmap)
+ \endlist
+ \row \li QByteArray
+ \li \list
+ \li If the byte array is null: 0xFFFFFFFF (quint32)
+ \li Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
+ \endlist
+ \row \li \l QColor
+ \li \list
+ \li Color spec (qint8)
+ \li Alpha value (quint16)
+ \li Red value (quint16)
+ \li Green value (quint16)
+ \li Blue value (quint16)
+ \li Pad value (quint16)
+ \endlist
+ \row \li QCursor
+ \li \list
+ \li Shape ID (qint16)
+ \li If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
+ \endlist
+ \row \li QDate
+ \li \list
+ \li Julian day (quint32)
+ \endlist
+ \row \li QDateTime
+ \li \list
+ \li Date (QDate)
+ \li Time (QTime)
+ \li 0 for Qt::LocalTime, 1 for Qt::UTC (quint8)
+ \endlist
+ \row \li QEasingCurve
+ \li \list
+ \li type (quint8)
+ \li func (quint64)
+ \li hasConfig (bool)
+ \li If hasConfig is true then these fields follow:
+ \li list
+ \li period (double)
+ \li amplitude (double)
+ \li overshoot (double)
+ \endlist
+ \row \li QFont
+ \li \list
+ \li The family (QString)
+ \li The point size (qint16)
+ \li The style hint (quint8)
+ \li The char set (quint8)
+ \li The weight (quint8)
+ \li The font bits (quint8)
+ \endlist
+ \row \li QHash<Key, T>
+ \li \list
+ \li The number of items (quint32)
+ \li For all items, the key (Key) and value (T)
+ \endlist
+ \row \li QIcon
+ \li \list
+ \li The number of pixmap entries (quint32)
+ \li For all pixmap entries:
\list
- \o The pixmap (QPixmap)
- \o The file name (QString)
- \o The pixmap size (QSize)
- \o The \l{QIcon::Mode}{mode} (quint32)
- \o The \l{QIcon::State}{state} (quint32)
+ \li The pixmap (QPixmap)
+ \li The file name (QString)
+ \li The pixmap size (QSize)
+ \li The \l{QIcon::Mode}{mode} (quint32)
+ \li The \l{QIcon::State}{state} (quint32)
\endlist
\endlist
- \row \o QImage
- \o \list
- \o If the image is null a "null image" marker is saved;
+ \row \li QImage
+ \li \list
+ \li If the image is null a "null image" marker is saved;
otherwise the image is saved in PNG or BMP format (depending
on the stream version). If you want control of the format,
stream the image into a QBuffer (using QImageIO) and stream
that.
\endlist
- \row \o QKeySequence
- \o \list
- \o A QList<int>, where each integer is a key in the key sequence
- \endlist
- \row \o QLinkedList<T>
- \o \list
- \o The number of items (quint32)
- \o The items (T)
- \endlist
- \row \o QList<T>
- \o \list
- \o The number of items (quint32)
- \o The items (T)
- \endlist
- \row \o QMap<Key, T>
- \o \list
- \o The number of items (quint32)
- \o For all items, the key (Key) and value (T)
- \endlist
- \row \o QMargins
- \o \list
- \o left (int)
- \o top (int)
- \o right (int)
- \o bottom (int)
- \endlist
- \row \o QMatrix
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m21 (double)
- \o m22 (double)
- \o dx (double)
- \o dy (double)
- \endlist
- \row \o QMatrix4x4
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m13 (double)
- \o m14 (double)
- \o m21 (double)
- \o m22 (double)
- \o m23 (double)
- \o m24 (double)
- \o m31 (double)
- \o m32 (double)
- \o m33 (double)
- \o m34 (double)
- \o m41 (double)
- \o m42 (double)
- \o m43 (double)
- \o m44 (double)
- \endlist
- \row \o QPair<T1, T2>
- \o \list
- \o first (T1)
- \o second (T2)
- \endlist
- \row \o QPalette
- \o The disabled, active, and inactive color groups, each of which consists
+ \row \li QKeySequence
+ \li \list
+ \li A QList<int>, where each integer is a key in the key sequence
+ \endlist
+ \row \li QLinkedList<T>
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
+ \endlist
+ \row \li QList<T>
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
+ \endlist
+ \row \li QMap<Key, T>
+ \li \list
+ \li The number of items (quint32)
+ \li For all items, the key (Key) and value (T)
+ \endlist
+ \row \li QMargins
+ \li \list
+ \li left (int)
+ \li top (int)
+ \li right (int)
+ \li bottom (int)
+ \endlist
+ \row \li QMatrix
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li dx (double)
+ \li dy (double)
+ \endlist
+ \row \li QMatrix4x4
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m13 (double)
+ \li m14 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li m23 (double)
+ \li m24 (double)
+ \li m31 (double)
+ \li m32 (double)
+ \li m33 (double)
+ \li m34 (double)
+ \li m41 (double)
+ \li m42 (double)
+ \li m43 (double)
+ \li m44 (double)
+ \endlist
+ \row \li QPair<T1, T2>
+ \li \list
+ \li first (T1)
+ \li second (T2)
+ \endlist
+ \row \li QPalette
+ \li The disabled, active, and inactive color groups, each of which consists
of the following:
\list
- \o foreground (QBrush)
- \o button (QBrush)
- \o light (QBrush)
- \o midlight (QBrush)
- \o dark (QBrush)
- \o mid (QBrush)
- \o text (QBrush)
- \o brightText (QBrush)
- \o buttonText (QBrush)
- \o base (QBrush)
- \o background (QBrush)
- \o shadow (QBrush)
- \o highlight (QBrush)
- \o highlightedText (QBrush)
- \o link (QBrush)
- \o linkVisited (QBrush)
- \endlist
- \row \o QPen
- \o \list
- \o The pen styles (quint8)
- \o The pen width (quint16)
- \o The pen color (QColor)
- \endlist
- \row \o QPicture
- \o \list
- \o The size of the picture data (quint32)
- \o The raw bytes of picture data (char)
- \endlist
- \row \o QPixmap
- \o \list
- \o Save it as a PNG image.
- \endlist
- \row \o QPoint
- \o \list
- \o The x coordinate (qint32)
- \o The y coordinate (qint32)
- \endlist
- \row \o QQuaternion
- \o \list
- \o The scalar component (double)
- \o The x coordinate (double)
- \o The y coordinate (double)
- \o The z coordinate (double)
- \endlist
- \row \o QRect
- \o \list
- \o left (qint32)
- \o top (qint32)
- \o right (qint32)
- \o bottom (qint32)
- \endlist
- \row \o QRegExp
- \o \list
- \o The regexp pattern (QString)
- \o Case sensitivity (quint8)
- \o Regular expression syntax (quint8)
- \o Minimal matching (quint8)
- \endlist
- \row \o QRegion
- \o \list
- \o The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32)
- \o 10 (qint32)
- \o The number of rectangles (quint32)
- \o The rectangles in sequential order (QRect)
- \endlist
- \row \o QSize
- \o \list
- \o width (qint32)
- \o height (qint32)
- \endlist
- \row \o QString
- \o \list
- \o If the string is null: 0xFFFFFFFF (quint32)
- \o Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
- \endlist
- \row \o QTime
- \o \list
- \o Milliseconds since midnight (quint32)
- \endlist
- \row \o QTransform
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m13 (double)
- \o m21 (double)
- \o m22 (double)
- \o m23 (double)
- \o m31 (double)
- \o m32 (double)
- \o m33 (double)
- \endlist
- \row \o QUrl
- \o \list
- \o Holds an URL (QString)
- \endlist
- \row \o QVariant
- \o \list
- \o The type of the data (quint32)
- \o The null flag (qint8)
- \o The data of the specified type
- \endlist
- \row \o QVector2D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
- \endlist
- \row \o QVector3D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
- \o the z coordinate (double)
- \endlist
- \row \o QVector4D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
- \o the z coordinate (double)
- \o the w coordinate (double)
- \endlist
- \row \o QVector<T>
- \o \list
- \o The number of items (quint32)
- \o The items (T)
+ \li foreground (QBrush)
+ \li button (QBrush)
+ \li light (QBrush)
+ \li midlight (QBrush)
+ \li dark (QBrush)
+ \li mid (QBrush)
+ \li text (QBrush)
+ \li brightText (QBrush)
+ \li buttonText (QBrush)
+ \li base (QBrush)
+ \li background (QBrush)
+ \li shadow (QBrush)
+ \li highlight (QBrush)
+ \li highlightedText (QBrush)
+ \li link (QBrush)
+ \li linkVisited (QBrush)
+ \endlist
+ \row \li QPen
+ \li \list
+ \li The pen styles (quint8)
+ \li The pen width (quint16)
+ \li The pen color (QColor)
+ \endlist
+ \row \li QPicture
+ \li \list
+ \li The size of the picture data (quint32)
+ \li The raw bytes of picture data (char)
+ \endlist
+ \row \li QPixmap
+ \li \list
+ \li Save it as a PNG image.
+ \endlist
+ \row \li QPoint
+ \li \list
+ \li The x coordinate (qint32)
+ \li The y coordinate (qint32)
+ \endlist
+ \row \li QQuaternion
+ \li \list
+ \li The scalar component (double)
+ \li The x coordinate (double)
+ \li The y coordinate (double)
+ \li The z coordinate (double)
+ \endlist
+ \row \li QRect
+ \li \list
+ \li left (qint32)
+ \li top (qint32)
+ \li right (qint32)
+ \li bottom (qint32)
+ \endlist
+ \row \li QRegExp
+ \li \list
+ \li The regexp pattern (QString)
+ \li Case sensitivity (quint8)
+ \li Regular expression syntax (quint8)
+ \li Minimal matching (quint8)
+ \endlist
+ \row \li QRegion
+ \li \list
+ \li The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32)
+ \li 10 (qint32)
+ \li The number of rectangles (quint32)
+ \li The rectangles in sequential order (QRect)
+ \endlist
+ \row \li QSize
+ \li \list
+ \li width (qint32)
+ \li height (qint32)
+ \endlist
+ \row \li QString
+ \li \list
+ \li If the string is null: 0xFFFFFFFF (quint32)
+ \li Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
+ \endlist
+ \row \li QTime
+ \li \list
+ \li Milliseconds since midnight (quint32)
+ \endlist
+ \row \li QTransform
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m13 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li m23 (double)
+ \li m31 (double)
+ \li m32 (double)
+ \li m33 (double)
+ \endlist
+ \row \li QUrl
+ \li \list
+ \li Holds an URL (QString)
+ \endlist
+ \row \li QVariant
+ \li \list
+ \li The type of the data (quint32)
+ \li The null flag (qint8)
+ \li The data of the specified type
+ \endlist
+ \row \li QVector2D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
+ \endlist
+ \row \li QVector3D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
+ \li the z coordinate (double)
+ \endlist
+ \row \li QVector4D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
+ \li the z coordinate (double)
+ \li the w coordinate (double)
+ \endlist
+ \row \li QVector<T>
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
\endlist
\endtable
*/
diff --git a/doc/src/network/network-programming/bearermanagement.qdoc b/doc/src/network/network-programming/bearermanagement.qdoc
index bcedc85a59..91dc32c5a5 100644
--- a/doc/src/network/network-programming/bearermanagement.qdoc
+++ b/doc/src/network/network-programming/bearermanagement.qdoc
@@ -81,16 +81,16 @@ lists the major QNetworkSession functions and how they fit into the session and
hardware management categories:
\table 60%
-\header \o Interface management \o Session management
-\row \o QNetworkSession::stop() \o QNetworkSession::open()
-\row \o QNetworkSession::interface() \o QNetworkSession::close()
-\row \o QNetworkSession::state() \o QNetworkSession::isOpen()
-\row \o QNetworkSession::bytesWritten() \o QNetworkSession::migrate()
-\row \o QNetworkSession::bytesReceived() \o QNetworkSession::ignore()
-\row \o QNetworkSession::activeTime() \o QNetworkSession::accept()
-\row \o QNetworkSession::stateChanged() \o QNetworkSession::reject()
-\row \o \o QNetworkSession::opened()
-\row \o \o QNetworkSession::closed()
+\header \li Interface management \li Session management
+\row \li QNetworkSession::stop() \li QNetworkSession::open()
+\row \li QNetworkSession::interface() \li QNetworkSession::close()
+\row \li QNetworkSession::state() \li QNetworkSession::isOpen()
+\row \li QNetworkSession::bytesWritten() \li QNetworkSession::migrate()
+\row \li QNetworkSession::bytesReceived() \li QNetworkSession::ignore()
+\row \li QNetworkSession::activeTime() \li QNetworkSession::accept()
+\row \li QNetworkSession::stateChanged() \li QNetworkSession::reject()
+\row \li \li QNetworkSession::opened()
+\row \li \li QNetworkSession::closed()
\endtable
The state of the session represents the state of the underlying access point
@@ -242,27 +242,27 @@ determining the feature support:
\table
\header
- \o Platform
- \o Backend capabilities
+ \li Platform
+ \li Backend capabilities
\row
- \o Linux\unicode{0xAE}
- \o Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager}
+ \li Linux\unicode{0xAE}
+ \li Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager}
and \l {http://connman.net/}{ConnMan} / \l {http://ofono.org/}{oFono} APIs
which support interface notifications and starting and stopping of network
interfaces.
\row
- \o Windows\unicode{0xAE} XP
- \o This platform supports interface notifications without active polling.
+ \li Windows\unicode{0xAE} XP
+ \li This platform supports interface notifications without active polling.
\row
- \o Windows XP SP2+Hotfixes, Windows XP SP3, Windows Vista, Windows 7
- \o In addition to standard Windows XP wifi access point monitoring has been improved which includes the ability to start and stop wifi interfaces. This requires Windows to manage the wifi interfaces.
+ \li Windows XP SP2+Hotfixes, Windows XP SP3, Windows Vista, Windows 7
+ \li In addition to standard Windows XP wifi access point monitoring has been improved which includes the ability to start and stop wifi interfaces. This requires Windows to manage the wifi interfaces.
\row
- \o Mac OS\unicode{0xAE}
- \o This platform has full support by way of CoreWLAN offered in Mac OS 10.6. Previous
+ \li Mac OS\unicode{0xAE}
+ \li This platform has full support by way of CoreWLAN offered in Mac OS 10.6. Previous
versions of Mac OS - 10.5 and 10.4 have limited support.
\row
- \o All other platforms (*nix, Windows Mobile)
- \o This backend is the fallback for all platforms supports network interface notifications via active polling only.
+ \li All other platforms (*nix, Windows Mobile)
+ \li This backend is the fallback for all platforms supports network interface notifications via active polling only.
\endtable
*/
diff --git a/doc/src/printsupport/printing.qdoc b/doc/src/printsupport/printing.qdoc
index 5277d1c547..5447032a2b 100644
--- a/doc/src/printsupport/printing.qdoc
+++ b/doc/src/printsupport/printing.qdoc
@@ -112,7 +112,7 @@
too small for the higher resolutions of typical printers.
\table
- \row \o \bold{Printer and Painter Coordinate Systems}
+ \row \li \b{Printer and Painter Coordinate Systems}
The \l{QPrinter::}{paperRect()} and \l{QPrinter::}{pageRect()} functions
provide information about the size of the paper used for printing and the
@@ -126,7 +126,7 @@
rectangle, and painting operations will be clipped to the bounds of the
drawable part of the page.
- \o \inlineimage printer-rects.png
+ \li \inlineimage printer-rects.png
\endtable
The paint system automatically uses the correct device metrics when painting
@@ -164,12 +164,12 @@
functionality can be obtained via a function in the corresponding widget's API.
\table
- \header \o Widget \o Printing function \o Accepts
- \row \o QGraphicsView \o QGraphicsView::render() \o QPainter
- \row \o QSvgWidget \o QSvgRenderer::render() \o QPainter
- \row \o QTextEdit \o QTextDocument::print() \o QPrinter
- \row \o QTextLayout \o QTextLayout::draw() \o QPainter
- \row \o QTextLine \o QTextLine::draw() \o QPainter
+ \header \li Widget \li Printing function \li Accepts
+ \row \li QGraphicsView \li QGraphicsView::render() \li QPainter
+ \row \li QSvgWidget \li QSvgRenderer::render() \li QPainter
+ \row \li QTextEdit \li QTextDocument::print() \li QPrinter
+ \row \li QTextLayout \li QTextLayout::draw() \li QPainter
+ \row \li QTextLine \li QTextLine::draw() \li QPainter
\endtable
QTextEdit requires a QPrinter rather than a QPainter because it uses information
diff --git a/doc/src/sql/sql-programming/qsqldatatype-table.qdoc b/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
index bc1c8b3c13..a7e03cf28f 100644
--- a/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
+++ b/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
@@ -48,518 +48,518 @@
\table 90%
\header
- \o IBM DB2 data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li IBM DB2 data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit Single-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit Single-precision floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Fixed-length, null-terminated character string
- \o Mapped to QString
+ \li CHAR
+ \li Fixed-length, null-terminated character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Null-terminated varying length string
- \o Mapped to QString
+ \li VARCHAR
+ \li Null-terminated varying length string
+ \li Mapped to QString
\row
- \o LONG VARCHAR
- \o Not null-terminated varying length character string
- \o Mapped to QString
+ \li LONG VARCHAR
+ \li Not null-terminated varying length character string
+ \li Mapped to QString
\row
- \o BLOB
- \o Not null-terminated varying binary string with 4-byte string
+ \li BLOB
+ \li Not null-terminated varying binary string with 4-byte string
length indicator
- \o Mapped to QByteArray
+ \li Mapped to QByteArray
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Null-terminated character string of the following format:
+ \li DATE
+ \li Null-terminated character string of the following format:
yyyy-mm-dd
- \o Mapped to QDate
+ \li Mapped to QDate
\row
- \o TIME
- \o Null-terminated character string of the following format: hh.mm.ss
- \o Mapped to QTime
+ \li TIME
+ \li Null-terminated character string of the following format: hh.mm.ss
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Null-terminated character string of the following format: yyyy-mm-dd-hh.mm.ss.nnnnnn
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Null-terminated character string of the following format: yyyy-mm-dd-hh.mm.ss.nnnnnn
+ \li Mapped to QDateTime
\endtable
\section2 Borland InterBase Data Types
\table 90%
\header
- \o Borland InterBase data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Borland InterBase data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BOOLEAN
- \o Boolean
- \o bool
+ \li BOOLEAN
+ \li Boolean
+ \li bool
\row
- \o TINYINT
- \o 8 bit signed integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit signed integer
+ \li typedef qint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT LONG
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT LONG
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL FLOAT
- \o 32-bit floating point
- \o By default mapping to QString
+ \li REAL FLOAT
+ \li 32-bit floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit floating point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit floating point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o VARCHAR STRING
- \o Character string, Unicode
- \o Mapped to QString
+ \li VARCHAR STRING
+ \li Character string, Unicode
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Displays date. Format: 'yyyy-mm-dd'
- \o Mapped to QDate
+ \li DATE
+ \li Displays date. Format: 'yyyy-mm-dd'
+ \li Mapped to QDate
\row
- \o TIME
- \o Displays time. Format is 'hh:mm:ss' in 24-hour format
- \o Mapped to QTime
+ \li TIME
+ \li Displays time. Format is 'hh:mm:ss' in 24-hour format
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Displays a timestamp. Format is 'yyyy-mm-dd hh:mm:ss'
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Displays a timestamp. Format is 'yyyy-mm-dd hh:mm:ss'
+ \li Mapped to QDateTime
\endtable
\section2 MySQL Data Types
\table 90%
\header
- \o MySQL data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li MySQL data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o TINYINT
- \o 8 bit signed integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit signed integer
+ \li typedef qint8
\row
- \o TINYINT UNSIGNED
- \o 8 bit unsigned integer
- \o typedef quint8
+ \li TINYINT UNSIGNED
+ \li 8 bit unsigned integer
+ \li typedef quint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o SMALLINT UNSIGNED
- \o 16-bit unsigned integer
- \o typedef quint16
+ \li SMALLINT UNSIGNED
+ \li 16-bit unsigned integer
+ \li typedef quint16
\row
- \o INT
- \o 32-bit signed integer
- \o typedef qint32
+ \li INT
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o INT UNSIGNED
- \o 32-bit unsigned integer
- \o typedef quint32
+ \li INT UNSIGNED
+ \li 32-bit unsigned integer
+ \li typedef quint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o FLOAT
- \o 32-bit Floating Point
- \o By default mapping to QString
+ \li FLOAT
+ \li 32-bit Floating Point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit Floating Point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit Floating Point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Character string
- \o Mapped to QString
+ \li CHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character string
- \o Mapped to QString
+ \li VARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o TINYTEXT
- \o Character string
- \o Mapped to QString
+ \li TINYTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o TEXT
- \o Character string
- \o Mapped to QString
+ \li TEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o MEDIUMTEXT
- \o Character string
- \o Mapped to QString
+ \li MEDIUMTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o LONGTEXT
- \o Character string
- \o Mapped to QString
+ \li LONGTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o all BLOB types
- \o BLOB
- \o Mapped to QByteArray
+ \li all BLOB types
+ \li BLOB
+ \li Mapped to QByteArray
\row
- \o DATE
- \o Date without Time
- \o Mapped to QDate
+ \li DATE
+ \li Date without Time
+ \li Mapped to QDate
\row
- \o DATETIME
- \o Date and Time
- \o Mapped to QDateTime
+ \li DATETIME
+ \li Date and Time
+ \li Mapped to QDateTime
\row
- \o TIMESTAMP
- \o Date and Time
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Date and Time
+ \li Mapped to QDateTime
\row
- \o TIME
- \o Time
- \o Mapped to QTime
+ \li TIME
+ \li Time
+ \li Mapped to QTime
\row
- \o YEAR
- \o Year (int)
- \o Mapped to QDateTime
+ \li YEAR
+ \li Year (int)
+ \li Mapped to QDateTime
\row
- \o ENUM
- \o Enumeration of Value Set
- \o Mapped to QString
+ \li ENUM
+ \li Enumeration of Value Set
+ \li Mapped to QString
\endtable
\section2 Oracle Call Interface Data Types
\table 90%
\header
- \o Oracle Call Interface data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Oracle Call Interface data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o NUMBER
- \o FLOAT, DOUBLE, PRECISIONc REAL
- \o By default mapping to QString
+ \li NUMBER
+ \li FLOAT, DOUBLE, PRECISIONc REAL
+ \li By default mapping to QString
\row
- \o NUMBER(38)
- \o INTEGER INT SMALLINT
- \o typedef qint8/16/32/64
+ \li NUMBER(38)
+ \li INTEGER INT SMALLINT
+ \li typedef qint8/16/32/64
\row
- \o NUMBER(p,s)
- \o NUMERIC(p,s) DECIMAL(p,s)a
- \o By default mapping to QString
+ \li NUMBER(p,s)
+ \li NUMERIC(p,s) DECIMAL(p,s)a
+ \li By default mapping to QString
\row
- \o NVARCHAR2(n)
- \o Character string (NATIONAL CHARACTER VARYING(n) NATIONAL
+ \li NVARCHAR2(n)
+ \li Character string (NATIONAL CHARACTER VARYING(n) NATIONAL
CHAR VARYING(n) NCHAR VARYING(n))
- \o Mapped to QString
+ \li Mapped to QString
\row
- \o NCHAR(n)
- \o Character string (NATIONAL CHARACTER(n) NATIONAL CHAR(n)
+ \li NCHAR(n)
+ \li Character string (NATIONAL CHARACTER(n) NATIONAL CHAR(n)
NCHAR(n))
- \o Mapped to QString
+ \li Mapped to QString
\row
- \o CHAR(n)
- \o Character string (CHARACTER(n) CHAR(n))
- \o Mapped to QString
+ \li CHAR(n)
+ \li Character string (CHARACTER(n) CHAR(n))
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o BLOB
- \o A binary large object
- \o Mapped to QByteArray
+ \li BLOB
+ \li A binary large object
+ \li Mapped to QByteArray
\row
- \o TIMESTAMP
- \o Year, month, and day values of date, as well as hour, minute,
+ \li TIMESTAMP
+ \li Year, month, and day values of date, as well as hour, minute,
and second values of time
- \o Mapped to QDateTime
+ \li Mapped to QDateTime
\endtable
\section2 ODBC Data Types
\table 90%
\header
- \o ODBC data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li ODBC data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BIT
- \o Boolean
- \o BOOL
+ \li BIT
+ \li Boolean
+ \li BOOL
\row
- \o TINYINT
- \o 8 bit integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit integer
+ \li typedef qint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit Single-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit Single-precision floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit Double floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit Double floating point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit Double floating point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit Double floating point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Character string
- \o Mapped to QString
+ \li CHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character string
- \o Mapped to QString
+ \li VARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o LONGVARCHAR
- \o Character string
- \o Mapped to QString
+ \li LONGVARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Character string
- \o Mapped to QDate
+ \li DATE
+ \li Character string
+ \li Mapped to QDate
\row
- \o TIME
- \o Character Time, Character string
- \o Mapped to QTime
+ \li TIME
+ \li Character Time, Character string
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Character Time, Character string
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Character Time, Character string
+ \li Mapped to QDateTime
\endtable
\section2 PostgreSQL Data Types
\table 90%
\header
- \o PostgreSQL data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li PostgreSQL data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BOOLEAN
- \o Boolean
- \o bool
+ \li BOOLEAN
+ \li Boolean
+ \li bool
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit variable-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit variable-precision floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit variable-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit variable-precision floating point
+ \li By default mapping to QString
\row
- \o DECIMAL VARIABLE
- \o user-specified precision, exact
- \o Mapped to QString
+ \li DECIMAL VARIABLE
+ \li user-specified precision, exact
+ \li Mapped to QString
\row
- \o NUMERIC VARIABLE
- \o user-specified precision, exact
- \o Mapped to QString
+ \li NUMERIC VARIABLE
+ \li user-specified precision, exact
+ \li Mapped to QString
\row
- \o VARCHAR
- \o variable-length character string
- \o Mapped to QString
+ \li VARCHAR
+ \li variable-length character string
+ \li Mapped to QString
\row
- \o CHARACTER
- \o Character string of fixed-length
- \o Mapped to QString
+ \li CHARACTER
+ \li Character string of fixed-length
+ \li Mapped to QString
\row
- \o TEXT
- \o Character string of variable-length
- \o Mapped to QString
+ \li TEXT
+ \li Character string of variable-length
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o TIMESTAMP
- \o 8 bytes, both date and time
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li 8 bytes, both date and time
+ \li Mapped to QDateTime
\row
- \o TIMESTAMP
- \o 8 bytes, both date and time, with time zone
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li 8 bytes, both date and time, with time zone
+ \li Mapped to QDateTime
\row
- \o DATE
- \o 4 bytes, dates only
- \o Mapped to QDate
+ \li DATE
+ \li 4 bytes, dates only
+ \li Mapped to QDate
\row
- \o TIME
- \o 8 bytes, times of day only 00:00:00.00 - 23:59:59.99
- \o Mapped to QTime
+ \li TIME
+ \li 8 bytes, times of day only 00:00:00.00 - 23:59:59.99
+ \li Mapped to QTime
\row
- \o TIME
- \o 12 bytes times of day only, with time zone 00:00:00.00+12
- \o Mapped to QDateTime
+ \li TIME
+ \li 12 bytes times of day only, with time zone 00:00:00.00+12
+ \li Mapped to QDateTime
\endtable
\section2 QSQLITE SQLite version 3 Data Types
\table 90%
\header
- \o QSQLITE SQLite version 3 data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li QSQLITE SQLite version 3 data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o NULL
- \o NULL value.
- \o NULL
+ \li NULL
+ \li NULL value.
+ \li NULL
\row
- \o INTEGER
- \o Signed integer, stored in 8, 16, 24, 32, 48, or 64-bits
+ \li INTEGER
+ \li Signed integer, stored in 8, 16, 24, 32, 48, or 64-bits
depending on the magnitude of the value.
- \o typedef qint8/16/32/64
+ \li typedef qint8/16/32/64
\row
- \o REAL
- \o 64-bit floating point value.
- \o By default mapping to QString
+ \li REAL
+ \li 64-bit floating point value.
+ \li By default mapping to QString
\row
- \o TEXT
- \o Character string (UTF-8, UTF-16BE or UTF-16-LE).
- \o Mapped to QString
+ \li TEXT
+ \li Character string (UTF-8, UTF-16BE or UTF-16-LE).
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o BLOB
- \o The value is a BLOB of data, stored exactly as it was input.
- \o Mapped to QByteArray
+ \li BLOB
+ \li The value is a BLOB of data, stored exactly as it was input.
+ \li Mapped to QByteArray
\endtable
\section2 Sybase Adaptive Server Data Types
\table 90%
\header
- \o Sybase Adaptive Server data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Sybase Adaptive Server data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BINARY
- \o Describes a fixed-length binary value up to 255 bytes in size.
- \o Mapped to QByteArray
+ \li BINARY
+ \li Describes a fixed-length binary value up to 255 bytes in size.
+ \li Mapped to QByteArray
\row
- \o CHAR
- \o Character String
- \o Mapped to QString
+ \li CHAR
+ \li Character String
+ \li Mapped to QString
\row
- \o DATETIME
- \o Date and time. Range: 1753-01-01 00:00:00 through 9999-12-31 23:59:59.
- \o Mapped to QDateTime
+ \li DATETIME
+ \li Date and time. Range: 1753-01-01 00:00:00 through 9999-12-31 23:59:59.
+ \li Mapped to QDateTime
\row
- \o NCHAR
- \o Character String of fixed length
- \o Mapped to QString
+ \li NCHAR
+ \li Character String of fixed length
+ \li Mapped to QString
\row
- \o NVARACHAR
- \o Character String of variable length
- \o Mapped to QString
+ \li NVARACHAR
+ \li Character String of variable length
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character String of fixed length
- \o Mapped to QString
+ \li VARCHAR
+ \li Character String of fixed length
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o TIMESTAMP
- \o A unique number within a database
- \o Mapped to QString
+ \li TIMESTAMP
+ \li A unique number within a database
+ \li Mapped to QString
\row
- \o SMALLDATETIME
- \o Date and time. Range: 1900-01-01 00:00 through 2079-12-31 23:59
- \o Mapped to QDateTime
+ \li SMALLDATETIME
+ \li Date and time. Range: 1900-01-01 00:00 through 2079-12-31 23:59
+ \li Mapped to QDateTime
\row
- \o UNICHAR
- \o Character String of fixed length.(Unicode)
- \o Mapped to QString
+ \li UNICHAR
+ \li Character String of fixed length.(Unicode)
+ \li Mapped to QString
\row
- \o UNIVARCHAR
- \o Character String of variable length.(Unicode)
- \o Mapped to QString
+ \li UNIVARCHAR
+ \li Character String of variable length.(Unicode)
+ \li Mapped to QString
\row
- \o VARBINARY
- \o Describes a variable-length binary value up to 255 bytes in size
- \o Mapped to QByteArray
+ \li VARBINARY
+ \li Describes a variable-length binary value up to 255 bytes in size
+ \li Mapped to QByteArray
\endtable
\section2 SQLite Version 2
diff --git a/doc/src/sql/sql-programming/sql-driver.qdoc b/doc/src/sql/sql-programming/sql-driver.qdoc
index 667b9eba54..eec61abd15 100644
--- a/doc/src/sql/sql-programming/sql-driver.qdoc
+++ b/doc/src/sql/sql-programming/sql-driver.qdoc
@@ -49,18 +49,18 @@
are provided with Open Source Versions of Qt.
\table
- \header \o Driver name \o DBMS
- \row \o \link #QDB2 QDB2\endlink \o IBM DB2 (version 7.1 and above)
- \row \o \link #QIBASE QIBASE\endlink \o Borland InterBase
- \row \o \link #QMYSQL QMYSQL\endlink \o MySQL
- \row \o \link #QOCI QOCI\endlink \o Oracle Call Interface Driver
- \row \o \link #QODBC QODBC\endlink
- \o Open Database Connectivity (ODBC) - Microsoft SQL Server and other
+ \header \li Driver name \li DBMS
+ \row \li \link #QDB2 QDB2\endlink \li IBM DB2 (version 7.1 and above)
+ \row \li \link #QIBASE QIBASE\endlink \li Borland InterBase
+ \row \li \link #QMYSQL QMYSQL\endlink \li MySQL
+ \row \li \link #QOCI QOCI\endlink \li Oracle Call Interface Driver
+ \row \li \link #QODBC QODBC\endlink
+ \li Open Database Connectivity (ODBC) - Microsoft SQL Server and other
ODBC-compliant databases
- \row \o \link #QPSQL QPSQL\endlink \o PostgreSQL (versions 7.3 and above)
- \row \o \link #QSQLITE2 QSQLITE2\endlink \o SQLite version 2
- \row \o \link #QSQLITE QSQLITE\endlink \o SQLite version 3
- \row \o \link #QTDS QTDS\endlink \o Sybase Adaptive Server \note obsolete from Qt 4.7
+ \row \li \link #QPSQL QPSQL\endlink \li PostgreSQL (versions 7.3 and above)
+ \row \li \link #QSQLITE2 QSQLITE2\endlink \li SQLite version 2
+ \row \li \link #QSQLITE QSQLITE\endlink \li SQLite version 3
+ \row \li \link #QTDS QTDS\endlink \li Sybase Adaptive Server \note obsolete from Qt 4.7
\endtable
SQLite is the in-process database system with the best test coverage
@@ -69,7 +69,7 @@
Linux. The completeness of the support for other systems depends on the
availability and quality of client libraries.
- \bold{Note:} To build a driver plugin you need to have the appropriate
+ \b{Note:} To build a driver plugin you need to have the appropriate
client library for your Database Management System (DBMS). This provides
access to the API exposed by the DBMS, and is typically shipped with it.
Most installation programs also allow you to install "development
@@ -123,7 +123,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.cpp 2
- \bold{Note:} \c{@outval1} and \c{@outval2} are variables local to the current
+ \b{Note:} \c{@outval1} and \c{@outval2} are variables local to the current
connection and will not be affected by queries sent from another host
or connection.
@@ -185,59 +185,59 @@
\list
- \o Download the following components:
+ \li Download the following components:
\list
- \o \c{MinGW-5.1.6.exe}
- \o \c{mingw-utils-0.3.tar.gz}
- \o Qt sources, e.g. \c{qt-everywhere-opensource-src-4.6.2.zip}
- \o \c{mysql-5.1.35-win32.msi}
+ \li \c{MinGW-5.1.6.exe}
+ \li \c{mingw-utils-0.3.tar.gz}
+ \li Qt sources, e.g. \c{qt-everywhere-opensource-src-4.6.2.zip}
+ \li \c{mysql-5.1.35-win32.msi}
\endlist
- \o Install \c{MinGW-5.1.6.exe} in, e.g. \c{C:\MinGW}.
+ \li Install \c{MinGW-5.1.6.exe} in, e.g. \c{C:\MinGW}.
- \o Extract \c{mingw-utils-0.3.tar.gz} into, e.g. \c{C:\MinGW}.
+ \li Extract \c{mingw-utils-0.3.tar.gz} into, e.g. \c{C:\MinGW}.
- \o Add the path for \c{MinGW-5.1.6.exe} to your \c{PATH} variable,
+ \li Add the path for \c{MinGW-5.1.6.exe} to your \c{PATH} variable,
e.g. \c{C:\MinGW\bin;}
- \o Extract the Qt sources, (\c{qt-everywhere-opensource-src-4.6.2.zip}),
+ \li Extract the Qt sources, (\c{qt-everywhere-opensource-src-4.6.2.zip}),
into, e.g. \c{C:\Qt}.
- \o Add the path for the eventual Qt binary to your \c{PATH} variable,
+ \li Add the path for the eventual Qt binary to your \c{PATH} variable,
e.g. \c{C:\Qt\4.6.2\bin;}.
- \o Install MySQL (\c{mysql-5.1.35-win32.msi}), customizing the
+ \li Install MySQL (\c{mysql-5.1.35-win32.msi}), customizing the
components. Select only the headers and libraries. Install in,
e.g. \c{C:\MySQL\MySQL51}.
- \o Open the DOS prompt, go to \c{C:\MySQL\MySQL51\lib\opt}, and run
+ \li Open the DOS prompt, go to \c{C:\MySQL\MySQL51\lib\opt}, and run
the following commands:
\list
- \o \c{reimp -d libmysql.lib}
- \o \c{dlltool -k -d libmysql.def -l libmysql.a}
+ \li \c{reimp -d libmysql.lib}
+ \li \c{dlltool -k -d libmysql.def -l libmysql.a}
\endlist
- \o Open the DOS prompt, go to \c{C:\Qt\4.6.2} and run the following commands:
+ \li Open the DOS prompt, go to \c{C:\Qt\4.6.2} and run the following commands:
\list
- \o \c{configure.exe -debug-and-release -platform win32-g++ -qt-sql-mysql
+ \li \c{configure.exe -debug-and-release -platform win32-g++ -qt-sql-mysql
-l mysql -I C:\MySQL\MySQL51\include -L C:\MySQL\MySQL51\lib\opt}
- \o \c{mingw32-make sub-src}
+ \li \c{mingw32-make sub-src}
\endlist
This step takes a long time.
- \o Open the DOS prompt, go to
+ \li Open the DOS prompt, go to
\c{C:\Qt\4.6.2\src\plugins\sqldrivers\mysql} and run the
following command:
\list
- \o \c{qmake "INCLUDEPATH+=C:\MySQL\MySQL51\include" "LIBS+=-L. mysql" mysql.pro}
+ \li \c{qmake "INCLUDEPATH+=C:\MySQL\MySQL51\include" "LIBS+=-L. mysql" mysql.pro}
\endlist
- \o Now the following libraries are ready in \c{C:\Qt\4.6.2\plugins\sqldrivers}.
+ \li Now the following libraries are ready in \c{C:\Qt\4.6.2\plugins\sqldrivers}.
\list
- \o \c{libqsqlmysql4.a}
- \o \c{libqsqlmysqld4.a}
- \o \c{qsqlmysql4.dll}
- \o \c{qsqlmysqld4.dll}
+ \li \c{libqsqlmysql4.a}
+ \li \c{libqsqlmysqld4.a}
+ \li \c{qsqlmysql4.dll}
+ \li \c{qsqlmysqld4.dll}
\endlist
To use the SDK and QtCreator directly, copy these libraries to
your \c{C:\Qt\...\qt\plugins\sqldrivers\}, and copy
@@ -287,8 +287,8 @@
Oracle library files required to build the driver:
\list
- \i \c libclntsh.so (all versions)
- \i \c libwtc9.so (only Oracle 9)
+ \li \c libclntsh.so (all versions)
+ \li \c libwtc9.so (only Oracle 9)
\endlist
Tell \c qmake where to find the Oracle header files and shared
@@ -301,7 +301,7 @@
Instant Client Package SDK (you need to adjust the version number accordingly):
\snippet doc/src/snippets/code/doc_src_sql-driver.qdoc 7
- \bold{Note:} If you are using the Oracle Instant Client package,
+ \b{Note:} If you are using the Oracle Instant Client package,
you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin
and when running an application that uses the OCI SQL plugin. You can
avoid this requirement by setting and RPATH and listing all of the
@@ -331,7 +331,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.qdoc 9
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QODBC
\section2 QODBC for Open Database Connectivity (ODBC)
@@ -345,7 +345,7 @@
driver manager that is installed on your system. The QODBC plugin
then allows you to use these data sources in your Qt applications.
- \bold{Note:} You should use native drivers in preference to the ODBC
+ \b{Note:} You should use native drivers in preference to the ODBC
driver where they are available. ODBC support can be used as a fallback
for compliant databases if no native drivers are available.
@@ -396,7 +396,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.cpp 10
- \bold{Note:} The value returned by the stored procedure's return statement
+ \b{Note:} The value returned by the stored procedure's return statement
is discarded.
\section3 ODBC Unicode Support
@@ -435,7 +435,7 @@
If you are not using a Microsoft compiler, replace \c nmake with \c
make in the line above.
- \bold{Note:} This database plugin is not officially supported for Windows CE.
+ \b{Note:} This database plugin is not officially supported for Windows CE.
\target QPSQL
\section2 QPSQL for PostgreSQL (Version 7.3 and Above)
@@ -496,7 +496,7 @@
Users of MinGW may wish to consult the following online document:
\l{PostgreSQL MinGW/Native Windows}.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QTDS
\section2 QTDS for Sybase Adaptive Server
@@ -515,11 +515,11 @@
Under Unix, two libraries are available which support the TDS protocol:
\list
- \i FreeTDS, a free implementation of the TDS protocol
+ \li FreeTDS, a free implementation of the TDS protocol
(\l{http://www.freetds.org}). Note that FreeTDS is not yet stable,
so some functionality may not work as expected.
- \i Sybase Open Client, available from \l{http://www.sybase.com}.
+ \li Sybase Open Client, available from \l{http://www.sybase.com}.
Note for Linux users: Get the Open Client RPM from
\l{http://linux.sybase.com}.
\endlist
@@ -545,7 +545,7 @@
are not using a Microsoft compiler, replace \c nmake with \c make in
the line above.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QDB2
\section2 QDB2 for IBM DB2 (Version 7.1 and Above)
@@ -582,7 +582,7 @@
If you are not using a Microsoft compiler, replace \c nmake
with \c make in the line above.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QSQLITE2
\section2 QSQLITE2 for SQLite Version 2
@@ -745,7 +745,7 @@
Note that \c{C:\interbase\bin} must be in the \c PATH.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target troubleshooting
\section1 Troubleshooting
@@ -763,16 +763,16 @@
make sure that the following requirements are met:
\list
- \i Ensure that you are using a shared Qt library; you cannot use the
+ \li Ensure that you are using a shared Qt library; you cannot use the
plugins with a static build.
- \i Ensure that the plugin is in the correct directory. You can use
+ \li Ensure that the plugin is in the correct directory. You can use
QApplication::libraryPaths() to determine where Qt looks for plugins.
- \i Ensure that the client libraries of the DBMS are available on the
+ \li Ensure that the client libraries of the DBMS are available on the
system. On Unix, run the command \c{ldd} and pass the name of the
plugin as parameter, for example \c{ldd libqsqlmysql.so}. You will
get a warning if any of the client libraries couldn't be found.
On Windows, you can use Visual Studio's dependency walker.
- \i Compile Qt with \c{QT_DEBUG_COMPONENT} defined to get very verbose
+ \li Compile Qt with \c{QT_DEBUG_COMPONENT} defined to get very verbose
debug output when loading plugins.
\endlist
diff --git a/doc/src/sql/sql-programming/sql-programming.qdoc b/doc/src/sql/sql-programming/sql-programming.qdoc
index 787b48718d..6ebb40b755 100644
--- a/doc/src/sql/sql-programming/sql-programming.qdoc
+++ b/doc/src/sql/sql-programming/sql-programming.qdoc
@@ -52,18 +52,18 @@
\section1 Topics:
\list
- \o \l{Database Classes}
- \o \l{Connecting to Databases}
+ \li \l{Database Classes}
+ \li \l{Connecting to Databases}
\list
- \o \l{SQL Database Drivers}
+ \li \l{SQL Database Drivers}
\endlist
- \o \l{Executing SQL Statements}
+ \li \l{Executing SQL Statements}
\list
- \o \l{Data Types for Qt-supported Database Systems}
+ \li \l{Data Types for Qt-supported Database Systems}
\endlist
- \o \l{Using the SQL Model Classes}
- \o \l{Presenting Data in a Table View}
- \o \l{Creating Data-Aware Forms}
+ \li \l{Using the SQL Model Classes}
+ \li \l{Presenting Data in a Table View}
+ \li \l{Creating Data-Aware Forms}
\endlist
\section1 Database Classes
@@ -338,12 +338,12 @@
QSqlTableModel, and QSqlRelationalTableModel.
\table
- \row \o QSqlQueryModel
- \o A read-only model based on an arbitrary SQL query.
- \row \o QSqlTableModel
- \o A read-write model that works on a single table.
- \row \o QSqlRelationalTableModel
- \o A QSqlTableModel subclass with foreign key support.
+ \row \li QSqlQueryModel
+ \li A read-only model based on an arbitrary SQL query.
+ \row \li QSqlTableModel
+ \li A read-write model that works on a single table.
+ \row \li QSqlRelationalTableModel
+ \li A QSqlTableModel subclass with foreign key support.
\endtable
These classes derive from QAbstractTableModel (which in turn
@@ -435,8 +435,8 @@
pitfalls, though:
\list
- \o Without any caching, performance may drop significantly.
- \o If you modify a primary key, the record might slip through
+ \li Without any caching, performance may drop significantly.
+ \li If you modify a primary key, the record might slip through
your fingers while you are trying to populate it.
\endlist
@@ -450,8 +450,8 @@
that \c authorid is a foreign key.
\table
- \row \o \inlineimage noforeignkeys.png
- \o \inlineimage foreignkeys.png
+ \row \li \inlineimage noforeignkeys.png
+ \li \inlineimage foreignkeys.png
\endtable
The screenshot on the left shows a plain QSqlTableModel in a
diff --git a/doc/src/widgets/addressbook-fr.qdoc b/doc/src/widgets/addressbook-fr.qdoc
index 4df19d015f..edd53239d0 100644
--- a/doc/src/widgets/addressbook-fr.qdoc
+++ b/doc/src/widgets/addressbook-fr.qdoc
@@ -40,10 +40,10 @@
par Qt, tel que:
\list
- \o Les Widgets et leur mise en page à l'aide des layouts
- \o Les signaux et slots
- \o Les structures de données de collections
- \o Les entrées/sorties
+ \li Les Widgets et leur mise en page à l'aide des layouts
+ \li Les signaux et slots
+ \li Les structures de données de collections
+ \li Les entrées/sorties
\endlist
Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt}
@@ -54,13 +54,13 @@
Les chapitres du tutoriel:
\list 1
- \o \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
- \o \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
- \o \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments}
- \o \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses}
- \o \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
- \o \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
- \o \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées}
+ \li \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
+ \li \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
+ \li \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments}
+ \li \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses}
+ \li \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
+ \li \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
+ \li \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées}
\endlist
La petite application que nous développerons ici ne possède pas tous les éléments
@@ -99,10 +99,10 @@
Trois fichiers sont nécessaires à l'implémentation de ce carnet d'adresses:
\list
- \o \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook,
- \o \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe
+ \li \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook,
+ \li \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe
\c AddressBook
- \o \c{main.cpp} - le fichier qui contient la méthode \c main() , et
+ \li \c{main.cpp} - le fichier qui contient la méthode \c main() , et
une instance de la classe \c AddressBook.
\endlist
@@ -116,13 +116,13 @@
ou modifier le comportement d'un widget présente les avantages suivants:
\list
- \o La possibilité d'implémenter des méthodes virtuelles et des méthodes
+ \li La possibilité d'implémenter des méthodes virtuelles et des méthodes
virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilité
d'utiliser l'implémentation de la classe mère si besoin est.
- \o Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
+ \li Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
afin que les autres parties de l'application n'aient pas à se soucier de chacun des
widgets qui forment l'interface utilisateur.
- \o La classe fille peut être utilisée pour créer de nombreux widgets personnalisés
+ \li La classe fille peut être utilisée pour créer de nombreux widgets personnalisés
dans une même application ou bibliothèque, et le code de la classe fille peut être
réutilisé dans d'autres projets
\endlist
@@ -343,7 +343,7 @@
La méthode \c submitContact() peut être divisée en trois parties:
\list 1
- \o Nous extrayons les détails du contact depuis \c nameLine et \c addressText
+ \li Nous extrayons les détails du contact depuis \c nameLine et \c addressText
et les stockons dans des objets QString. Nous les validons pour s'assurer
que l'utilisateur n'a pas cliqué sur "Add" avec des champs de saisie
vides; sinon un message est affiché avec QMessageBox pour rappeller à
@@ -351,7 +351,7 @@
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
- \o Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts
+ \li Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts
existant n'entre en conflit avec le nouveau, nous l'ajoutons à
\c contacts et nous affichons un QMessageBox pour informer l'utilisateur
que le contact a été ajouté.
@@ -363,7 +363,7 @@
Notre objet \c contacts est basé sur des paires clé-valeur formés par
le nom et l'adresse, nous voulons nous assurer que la \e clé est unique.
- \o Une fois que les deux vérifications précédentes ont été traitées,
+ \li Une fois que les deux vérifications précédentes ont été traitées,
nous restaurons les boutons à leur état normal à l'aide du code
suivant:
@@ -482,8 +482,8 @@
sur \c contact dans la méthode \c next(), et ensuite:
\list
- \o Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons
- \o Si l'itérateur est à la fin de \c contacts, nous changeons sa position
+ \li Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons
+ \li Si l'itérateur est à la fin de \c contacts, nous changeons sa position
jusqu'au début de \c contacts. Cela donne l'illusion que notre QMap
fonctionne comme une liste circulaire.
\endlist
@@ -497,11 +497,11 @@
itérateur sur \c contacts et ensuite:
\list
- \o Si l'itérateur est à la fin de \c contacts, on réinitialise
+ \li Si l'itérateur est à la fin de \c contacts, on réinitialise
l'affichage et on retourne.
- \o Si l'itérateur est au début de \c contacts, on change sa
+ \li Si l'itérateur est au début de \c contacts, on change sa
position jusqu'à la fin
- \o Ensuite, on décrémente l'itérateur
+ \li Ensuite, on décrémente l'itérateur
\endlist
\snippet tutorials/addressbook/part3/addressbook.cpp previous() function
@@ -538,9 +538,9 @@
Dans ce chapitre, on définit l'énumération \c Mode avec trois valeurs possibles.
\list
- \o \c{NavigationMode},
- \o \c{AddingMode}, et
- \o \c{EditingMode}.
+ \li \c{NavigationMode},
+ \li \c{AddingMode}, et
+ \li \c{EditingMode}.
\endlist
\section1 Définition de la classe AddressBook
diff --git a/doc/src/widgets/addressbook.qdoc b/doc/src/widgets/addressbook.qdoc
index 96c96df177..27bdb0fac4 100644
--- a/doc/src/widgets/addressbook.qdoc
+++ b/doc/src/widgets/addressbook.qdoc
@@ -47,10 +47,10 @@
components of Qt, including:
\list
- \o Widgets and layout managers
- \o Container classes
- \o Signals and slots
- \o Input and output devices
+ \li Widgets and layout managers
+ \li Container classes
+ \li Signals and slots
+ \li Input and output devices
\endlist
If you are new to Qt, we recommend reading \l{How to Learn Qt} first.
@@ -58,13 +58,13 @@
Tutorial contents:
\list 1
- \o \l{tutorials/addressbook/part1}{Designing the User Interface}
- \o \l{tutorials/addressbook/part2}{Adding Addresses}
- \o \l{tutorials/addressbook/part3}{Navigating between Entries}
- \o \l{tutorials/addressbook/part4}{Editing and Removing Addresses}
- \o \l{tutorials/addressbook/part5}{Adding a Find Function}
- \o \l{tutorials/addressbook/part6}{Loading and Saving}
- \o \l{tutorials/addressbook/part7}{Additional Features}
+ \li \l{tutorials/addressbook/part1}{Designing the User Interface}
+ \li \l{tutorials/addressbook/part2}{Adding Addresses}
+ \li \l{tutorials/addressbook/part3}{Navigating between Entries}
+ \li \l{tutorials/addressbook/part4}{Editing and Removing Addresses}
+ \li \l{tutorials/addressbook/part5}{Adding a Find Function}
+ \li \l{tutorials/addressbook/part6}{Loading and Saving}
+ \li \l{tutorials/addressbook/part7}{Additional Features}
\endlist
The tutorial source code is located in \c{examples/tutorials/addressbook}.
@@ -105,11 +105,11 @@
There are three files used to implement this address book:
\list
- \o \c{addressbook.h} - the definition file for the \c AddressBook
+ \li \c{addressbook.h} - the definition file for the \c AddressBook
class,
- \o \c{addressbook.cpp} - the implementation file for the
+ \li \c{addressbook.cpp} - the implementation file for the
\c AddressBook class, and
- \o \c{main.cpp} - the file containing a \c main() function, with
+ \li \c{main.cpp} - the file containing a \c main() function, with
an instance of \c AddressBook.
\endlist
@@ -121,13 +121,13 @@
extend or change the behavior of a widget has the following advantages:
\list
- \o We can write implementations of virtual or pure virtual functions to
+ \li We can write implementations of virtual or pure virtual functions to
obtain exactly what we need, falling back on the base class's implementation
when necessary.
- \o It allows us to encapsulate parts of the user interface within a class,
+ \li It allows us to encapsulate parts of the user interface within a class,
so that the other parts of the application don't need to know about the
individual widgets in the user interface.
- \o The subclass can be used to create multiple custom widgets in the same
+ \li The subclass can be used to create multiple custom widgets in the same
application or library, and the code for the subclass can be reused in other
projects.
\endlist
@@ -340,14 +340,14 @@
The \c submitContact() function can be divided into three parts:
\list 1
- \o We extract the contact's details from \c nameLine and \c addressText
+ \li We extract the contact's details from \c nameLine and \c addressText
and store them in QString objects. We also validate to make sure that the
user did not click \gui Submit with empty input fields; otherwise, a
QMessageBox is displayed to remind the user for a name and address.
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
- \o We then proceed to check if the contact already exists. If it does not
+ \li We then proceed to check if the contact already exists. If it does not
exist, we add the contact to \c contacts and we display a QMessageBox to
inform the user that the contact has been added.
@@ -358,7 +358,7 @@
Our \c contacts object is based on key-value pairs of name and address,
hence, we want to ensure that \e key is unique.
- \o Once we have handled both cases mentioned above, we restore the push
+ \li Once we have handled both cases mentioned above, we restore the push
buttons to their normal state with the following code:
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3
@@ -471,9 +471,9 @@
for \c contacts and then:
\list
- \o If the iterator is not at the end of \c contacts, we increment it
+ \li If the iterator is not at the end of \c contacts, we increment it
by one.
- \o If the iterator is at the end of \c contacts, we move it to the
+ \li If the iterator is at the end of \c contacts, we move it to the
beginning of \c contacts. This gives us the illusion that our QMap is
working like a circularly-linked list.
\endlist
@@ -487,11 +487,11 @@
\c contacts and then:
\list
- \o If the iterator is at the end of \c contacts, we clear the
+ \li If the iterator is at the end of \c contacts, we clear the
display and return.
- \o If the iterator is at the beginning of \c contacts, we move it to
+ \li If the iterator is at the beginning of \c contacts, we move it to
the end.
- \o We then decrement the iterator by one.
+ \li We then decrement the iterator by one.
\endlist
\snippet tutorials/addressbook/part3/addressbook.cpp previous() function
@@ -524,9 +524,9 @@
Here we define the \c Mode enum with three different values:
\list
- \o \c{NavigationMode},
- \o \c{AddingMode}, and
- \o \c{EditingMode}.
+ \li \c{NavigationMode},
+ \li \c{AddingMode}, and
+ \li \c{EditingMode}.
\endlist
\section1 Defining the AddressBook Class
diff --git a/doc/src/widgets/modelview.qdoc b/doc/src/widgets/modelview.qdoc
index 536b521100..fdd25def31 100644
--- a/doc/src/widgets/modelview.qdoc
+++ b/doc/src/widgets/modelview.qdoc
@@ -55,16 +55,16 @@
such as:
\list
- \o The difference between standard and model/view widgets
- \o Adapters between forms and models
- \o Developing a simple model/view application
- \o Predefined models
- \o Intermediate topics such as:
+ \li The difference between standard and model/view widgets
+ \li Adapters between forms and models
+ \li Developing a simple model/view application
+ \li Predefined models
+ \li Intermediate topics such as:
\list
- \o Tree views
- \o Selection
- \o Delegates
- \o Debugging with model test
+ \li Tree views
+ \li Selection
+ \li Delegates
+ \li Debugging with model test
\endlist
\endlist
@@ -91,11 +91,11 @@
\table
\row
- \o Standard widgets use data that is part of the widget.
- \o \image standardwidget.png
+ \li Standard widgets use data that is part of the widget.
+ \li \image standardwidget.png
\row
- \o View classes operate on external data (the model)
- \o \image modelview.png
+ \li View classes operate on external data (the model)
+ \li \image modelview.png
\endtable
\section2 1.1 Standard Widgets
@@ -133,30 +133,30 @@
\table
\header
- \o Widget
- \o Standard Widget\br
+ \li Widget
+ \li Standard Widget\br
(an item based convenience class)
- \o Model/View View Class\br
+ \li Model/View View Class\br
(for use with external data)
\row
- \o \inlineimage listview.png
- \o \l QListWidget
- \o \l QListView
+ \li \inlineimage listview.png
+ \li \l QListWidget
+ \li \l QListView
\row
- \o \inlineimage tableview.png
- \o \l QTableWidget
- \o \l QTableView
+ \li \inlineimage tableview.png
+ \li \l QTableWidget
+ \li \l QTableView
\row
- \o \inlineimage treeview.png
- \o \l QTreeWidget
- \o \l QTreeView
+ \li \inlineimage treeview.png
+ \li \l QTreeWidget
+ \li \l QTreeView
\row
- \o \inlineimage columnview.png
- \o
- \o \l QColumnView shows a tree as a hierarchy of lists
+ \li \inlineimage columnview.png
+ \li
+ \li \l QColumnView shows a tree as a hierarchy of lists
\row
- \o \inlineimage modelview-combobox.png
- \o {2, 1} \l QComboBox can work as both a view class and also
+ \li \inlineimage modelview-combobox.png
+ \li {2, 1} \l QComboBox can work as both a view class and also
as a traditional widget
\endtable
@@ -212,8 +212,8 @@
things:
\list
- \o How many rows and columns should be displayed.
- \o What content should be printed into each cell.
+ \li How many rows and columns should be displayed.
+ \li What content should be printed into each cell.
\endlist
The model needs some code to respond to this.
@@ -271,33 +271,33 @@
\table
\header
- \o \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
- \o Meaning
- \o Type
+ \li \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
+ \li Meaning
+ \li Type
\row
- \o \l{Qt::ItemDataRole}{}Qt::DisplayRole
- \o text
- \o QString
+ \li \l{Qt::ItemDataRole}{}Qt::DisplayRole
+ \li text
+ \li QString
\row
- \o \l{Qt::ItemDataRole}{Qt::FontRole}
- \o font
- \o QFont
+ \li \l{Qt::ItemDataRole}{Qt::FontRole}
+ \li font
+ \li QFont
\row
- \o \l{Qt::ItemDataRole}{BackgroundRole}
- \o brush for the background of the cell
- \o QBrush
+ \li \l{Qt::ItemDataRole}{BackgroundRole}
+ \li brush for the background of the cell
+ \li QBrush
\row
- \o \l{Qt::ItemDataRole}{Qt::TextAlignmentRole}
- \o text alignment
- \o \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag}
+ \li \l{Qt::ItemDataRole}{Qt::TextAlignmentRole}
+ \li text alignment
+ \li \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag}
\row
- \o {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole}
- \o {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()},
+ \li {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole}
+ \li {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()},
sets checkboxes with \l{Qt::CheckState}{Qt::Checked}
or \l{Qt::CheckState}{Qt::Unchecked}
- \o {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
+ \li {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
\endtable
Refer to the Qt namespace documentation to learn more about the
@@ -490,27 +490,27 @@
\table
\row
- \o QStringListModel
- \o Stores a list of strings
+ \li QStringListModel
+ \li Stores a list of strings
\row
- \o QStandardItemModel
- \o Stores arbitrary hierarchical items
+ \li QStandardItemModel
+ \li Stores arbitrary hierarchical items
\row
- \o QFileSystemModel\br
+ \li QFileSystemModel\br
QDirModel
- \o Encapsulate the local file system
+ \li Encapsulate the local file system
\row
- \o QSqlQueryModel
- \o Encapsulate an SQL result set
+ \li QSqlQueryModel
+ \li Encapsulate an SQL result set
\row
- \o QSqlTableModel
- \o Encapsulates an SQL table
+ \li QSqlTableModel
+ \li Encapsulates an SQL table
\row
- \o QSqlRelationalTableModel
- \o Encapsulates an SQL table with foreign keys
+ \li QSqlRelationalTableModel
+ \li Encapsulates an SQL table with foreign keys
\row
- \o QSortFilterProxyModel
- \o Sorts and/or filters another model
+ \li QSortFilterProxyModel
+ \li Sorts and/or filters another model
\endtable
@@ -562,11 +562,11 @@
Other references to delegates in Qt Documentation:
\list
- \o \l{Spin Box Delegate Example}
- \o \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
- \o \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
- \o \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
- \o \l{QItemDelegate}{QItemDelegate Class Reference}
+ \li \l{Spin Box Delegate Example}
+ \li \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
+ \li \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
+ \li \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
+ \li \l{QItemDelegate}{QItemDelegate Class Reference}
\endlist
@@ -599,16 +599,16 @@
Qt but also in several good books.
\list 1
- \o \bold{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield,
+ \li \b{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield,
\e{Prentice Hall, 2nd edition}, ISBN 0-13-235416-0. Also available in
- German: \bold{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung},
+ German: \b{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung},
\e{Addison-Wesley}, ISBN 3-827327-29-6
- \o \bold{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin,
+ \li \b{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin,
\e{Open Source Press}, ISBN 1-59327-147-6.
- Translated from \bold{Qt 4, Einführung in die Applikationsentwicklung},
+ Translated from \b{Qt 4, Einführung in die Applikationsentwicklung},
\e{Open Source Press}, ISBN 3-937514-12-0.
- \o \bold{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8.
- \o \bold{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6.
+ \li \b{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8.
+ \li \b{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6.
This book covers Model/View programming on more than 150 pages.
\endlist
@@ -621,157 +621,157 @@
\table
\header
- \o Example name
- \o View class used
- \o Model used
- \o Aspects covered
- \o
- \row
- \o Team Leaders
- \o QListview
- \o QStringListModel
- \o
- \o Book 1, Chapter 10, Figure 10.6
- \row
- \o Directory Viewer
- \o QTreeView
- \o QDirModel
- \o
- \o Book 1, Chapter 10, Figure 10.7
- \row
- \o Color Names
- \o QListView
- \o QSortFilterProxyModel
+ \li Example name
+ \li View class used
+ \li Model used
+ \li Aspects covered
+ \li
+ \row
+ \li Team Leaders
+ \li QListview
+ \li QStringListModel
+ \li
+ \li Book 1, Chapter 10, Figure 10.6
+ \row
+ \li Directory Viewer
+ \li QTreeView
+ \li QDirModel
+ \li
+ \li Book 1, Chapter 10, Figure 10.7
+ \row
+ \li Color Names
+ \li QListView
+ \li QSortFilterProxyModel
applied to QStringListModel
- \o
- \o Book 1, Chapter 10, Figure 10.8
+ \li
+ \li Book 1, Chapter 10, Figure 10.8
\row
- \o Currencies
- \o QTableView
- \o custom model based on
+ \li Currencies
+ \li QTableView
+ \li custom model based on
QAbstractTableModel
- \o Read only
- \o Book 1, Chapter 10, Figure 10.10
+ \li Read only
+ \li Book 1, Chapter 10, Figure 10.10
\row
- \o Cities
- \o QTableView
- \o Custom model based on
+ \li Cities
+ \li QTableView
+ \li Custom model based on
QAbstractTableModel
- \o Read / write
- \o Book 1, Chapter 10, Figure 10.12
+ \li Read / write
+ \li Book 1, Chapter 10, Figure 10.12
\row
- \o Boolean Parser
- \o QTreeView
- \o Custom model based on
+ \li Boolean Parser
+ \li QTreeView
+ \li Custom model based on
QAbstractItemModel
- \o Read only
- \o Book 1, Chapter 10, Figure 10.14
+ \li Read only
+ \li Book 1, Chapter 10, Figure 10.14
\row
- \o Track Editor
- \o {2, 1} QTableWidget
- \o Custom delegate providing a custom editor
- \o Book 1, Chapter 10, Figure 10.15
+ \li Track Editor
+ \li {2, 1} QTableWidget
+ \li Custom delegate providing a custom editor
+ \li Book 1, Chapter 10, Figure 10.15
\row
- \o Four directory views
- \o QListView
+ \li Four directory views
+ \li QListView
QTableView
QTreeView
- \o QDirModel
- \o Demonstrates the use of multiple views
- \o Book2, Chapter 8.2
+ \li QDirModel
+ \li Demonstrates the use of multiple views
+ \li Book2, Chapter 8.2
\row
- \o Address Book
- \o QListView
+ \li Address Book
+ \li QListView
QTableView
QTreeView
- \o Custom model based on
+ \li Custom model based on
QAbstractTableModel
- \o Read / write
- \o Book2, Chapter 8.4
+ \li Read / write
+ \li Book2, Chapter 8.4
\row
- \o Address Book with sorting
- \o
- \o QProxyModel
- \o Introducing sort and filter capabilities
- \o Book2, Chapter 8.5
+ \li Address Book with sorting
+ \li
+ \li QProxyModel
+ \li Introducing sort and filter capabilities
+ \li Book2, Chapter 8.5
\row
- \o Address Book
+ \li Address Book
with checkboxes
- \o
- \o
- \o Introducing checkboxes in model/view
- \o Book2, Chapter 8.6
- \row
- \o Address Book with transposed grid
- \o
- \o Custom proxy Model based on QAbstractProxyModel
- \o Introducing a custom model
- \o Book2, Chapter 8.7
- \row
- \o Address Book with drag and drop
- \o
- \o
- \o Introducing drag and drop support
- \o Book2, Chapter 8.8
- \row
- \o Address Book with custom editor
- \o
- \o
- \o Introducing custom delegates
- \o Book2, Chapter 8.9
- \row
- \o Views
- \o QListView
+ \li
+ \li
+ \li Introducing checkboxes in model/view
+ \li Book2, Chapter 8.6
+ \row
+ \li Address Book with transposed grid
+ \li
+ \li Custom proxy Model based on QAbstractProxyModel
+ \li Introducing a custom model
+ \li Book2, Chapter 8.7
+ \row
+ \li Address Book with drag and drop
+ \li
+ \li
+ \li Introducing drag and drop support
+ \li Book2, Chapter 8.8
+ \row
+ \li Address Book with custom editor
+ \li
+ \li
+ \li Introducing custom delegates
+ \li Book2, Chapter 8.9
+ \row
+ \li Views
+ \li QListView
QTableView
QTreeView
- \o QStandardItemModel
- \o Read only
- \o Book 3, Chapter 5, figure 5-3
- \row
- \o Bardelegate
- \o QTableView
- \o
- \o Custom delegate for presentation based on QAbstractItemDelegate
- \o Book 3, Chapter 5, figure 5-5
- \row
- \o Editdelegate
- \o QTableView
- \o
- \o Custom delegate for editing based on QAbstractItemDelegate
- \o Book 3, Chapter 5, figure 5-6
- \row
- \o Singleitemview
- \o Custom view based on QAbstractItemView
- \o
- \o Custom view
- \o Book 3,
+ \li QStandardItemModel
+ \li Read only
+ \li Book 3, Chapter 5, figure 5-3
+ \row
+ \li Bardelegate
+ \li QTableView
+ \li
+ \li Custom delegate for presentation based on QAbstractItemDelegate
+ \li Book 3, Chapter 5, figure 5-5
+ \row
+ \li Editdelegate
+ \li QTableView
+ \li
+ \li Custom delegate for editing based on QAbstractItemDelegate
+ \li Book 3, Chapter 5, figure 5-6
+ \row
+ \li Singleitemview
+ \li Custom view based on QAbstractItemView
+ \li
+ \li Custom view
+ \li Book 3,
Chapter 5,
figure 5-7
\row
- \o listmodel
- \o QTableView
- \o Custom Model based on QAbstractTableModel
- \o Read only
- \o Book 3, Chapter 5, Figure 5-8
- \row
- \o treemodel
- \o QTreeView
- \o Custom Model based on QAbstractItemModel
- \o Read only
- \o Book 3, Chapter 5, Figure 5-10
- \row
- \o edit integers
- \o QListView
- \o Custom Model based on QAbstractListModel
- \o Read / write
- \o Book 3, Chapter 5, Listing 5-37, Figure 5-11
- \row
- \o sorting
- \o QTableView
- \o QSortFilterProxyModel applied to QStringListModel
- \o Demonstrates sorting
- \o Book 3, Chapter 5, Figure 5-12
+ \li listmodel
+ \li QTableView
+ \li Custom Model based on QAbstractTableModel
+ \li Read only
+ \li Book 3, Chapter 5, Figure 5-8
+ \row
+ \li treemodel
+ \li QTreeView
+ \li Custom Model based on QAbstractItemModel
+ \li Read only
+ \li Book 3, Chapter 5, Figure 5-10
+ \row
+ \li edit integers
+ \li QListView
+ \li Custom Model based on QAbstractListModel
+ \li Read / write
+ \li Book 3, Chapter 5, Listing 5-37, Figure 5-11
+ \row
+ \li sorting
+ \li QTableView
+ \li QSortFilterProxyModel applied to QStringListModel
+ \li Demonstrates sorting
+ \li Book 3, Chapter 5, Figure 5-12
\endtable
@@ -782,108 +782,108 @@
\table
\header
- \o Example name
- \o View class used
- \o Model used
- \o Aspects covered
- \row
- \o Address Book
- \o QTableView
- \o QAbstractTableModel
+ \li Example name
+ \li View class used
+ \li Model used
+ \li Aspects covered
+ \row
+ \li Address Book
+ \li QTableView
+ \li QAbstractTableModel
QSortFilterProxyModel
- \o Usage of QSortFilterProxyModel to generate different
+ \li Usage of QSortFilterProxyModel to generate different
subsets from one data pool
\row
- \o Basic Sort/Filter Model
- \o QTreeView
- \o QStandardItemModel
+ \li Basic Sort/Filter Model
+ \li QTreeView
+ \li QStandardItemModel
QSortFilterProxyModel
- \o
+ \li
\row
- \o Chart
- \o Custom view
- \o QStandardItemModel
- \o Designing custom views that cooperate with selection models
+ \li Chart
+ \li Custom view
+ \li QStandardItemModel
+ \li Designing custom views that cooperate with selection models
\row
- \o Color Editor Factory
- \o {2, 1} QTableWidget
- \o Enhancing the standard delegate with a new custom editor to choose colours
+ \li Color Editor Factory
+ \li {2, 1} QTableWidget
+ \li Enhancing the standard delegate with a new custom editor to choose colours
\row
- \o Combo Widget Mapper
- \o QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox
- \o QStandardItemModel
- \o Shows how a QComboBox can serve as a view class
+ \li Combo Widget Mapper
+ \li QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox
+ \li QStandardItemModel
+ \li Shows how a QComboBox can serve as a view class
\row
- \o Custom Sort/Filter Model
- \o QTreeView
- \o QStandardItemModel
+ \li Custom Sort/Filter Model
+ \li QTreeView
+ \li QStandardItemModel
QSortFilterProxyModel
- \o Subclass QSortFilterProxyModel for advanced sorting and filtering
+ \li Subclass QSortFilterProxyModel for advanced sorting and filtering
\row
- \o Dir View
- \o QTreeView
- \o QDirModel
- \o Very small example to demonstrate how to assign a model to a view
+ \li Dir View
+ \li QTreeView
+ \li QDirModel
+ \li Very small example to demonstrate how to assign a model to a view
\row
- \o Editable Tree Model
- \o QTreeView
- \o Custom tree model
- \o Comprehensive example for working with trees, demonstrates
+ \li Editable Tree Model
+ \li QTreeView
+ \li Custom tree model
+ \li Comprehensive example for working with trees, demonstrates
editing cells and tree structure with an underlying custom
model
\row
- \o Fetch More
- \o QListView
- \o Custom list model
- \o Dynamically changing model
- \row
- \o Frozen Column
- \o QTableView
- \o QStandardItemModel
- \o
- \row
- \o Interview
- \o Multiple
- \o Custom item model
- \o Multiple views
- \row
- \o Pixelator
- \o QTableView
- \o Custom table model
- \o Implementation of a custom delegate
- \row
- \o Puzzle
- \o QListView
- \o Custom list model
- \o Model/view with drag and drop
- \row
- \o Simple DOM Model
- \o QTreeView
- \o Custom tree model
- \o Read only example for a custom tree model
- \row
- \o Simple Tree Model
- \o QTreeView
- \o Custom tree model
- \o Read only example for a custom tree model
- \row
- \o Simple Widget Mapper
- \o QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
- \o QStandardItemModel
- \o Basic QDataWidgetMapper usage
- \row
- \o Spin Box Delegate
- \o QTableView
- \o QStandardItemModel
- \o Custom delegate that uses a spin box as a cell editor
- \row
- \o Spreadsheet
- \o {2, 1} QTableView
- \o Custom delegates
- \row
- \o Star Delegate
- \o {2, 1} QTableWidget
- \o Comprehensive custom delegate example.
+ \li Fetch More
+ \li QListView
+ \li Custom list model
+ \li Dynamically changing model
+ \row
+ \li Frozen Column
+ \li QTableView
+ \li QStandardItemModel
+ \li
+ \row
+ \li Interview
+ \li Multiple
+ \li Custom item model
+ \li Multiple views
+ \row
+ \li Pixelator
+ \li QTableView
+ \li Custom table model
+ \li Implementation of a custom delegate
+ \row
+ \li Puzzle
+ \li QListView
+ \li Custom list model
+ \li Model/view with drag and drop
+ \row
+ \li Simple DOM Model
+ \li QTreeView
+ \li Custom tree model
+ \li Read only example for a custom tree model
+ \row
+ \li Simple Tree Model
+ \li QTreeView
+ \li Custom tree model
+ \li Read only example for a custom tree model
+ \row
+ \li Simple Widget Mapper
+ \li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
+ \li QStandardItemModel
+ \li Basic QDataWidgetMapper usage
+ \row
+ \li Spin Box Delegate
+ \li QTableView
+ \li QStandardItemModel
+ \li Custom delegate that uses a spin box as a cell editor
+ \row
+ \li Spreadsheet
+ \li {2, 1} QTableView
+ \li Custom delegates
+ \row
+ \li Star Delegate
+ \li {2, 1} QTableWidget
+ \li Comprehensive custom delegate example.
\endtable
A \l{Model/View Programming}{reference document} for model/view technology
diff --git a/doc/src/widgets/widgets-and-layouts/focus.qdoc b/doc/src/widgets/widgets-and-layouts/focus.qdoc
index 374d5781ee..60f05948b4 100644
--- a/doc/src/widgets/widgets-and-layouts/focus.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/focus.qdoc
@@ -51,11 +51,11 @@
\list 1
- \o The user presses \key Tab (or \key Shift+Tab).
- \o The user clicks a widget.
- \o The user presses a keyboard shortcut.
- \o The user uses the mouse wheel.
- \o The user moves the focus to a window, and the application must
+ \li The user presses \key Tab (or \key Shift+Tab).
+ \li The user clicks a widget.
+ \li The user presses a keyboard shortcut.
+ \li The user uses the mouse wheel.
+ \li The user moves the focus to a window, and the application must
determine which widget within the window should get the focus.
\endlist
@@ -93,14 +93,14 @@
\list 1
- \o If the program can determine whether the field is needed, it can
+ \li If the program can determine whether the field is needed, it can
move focus there when the user finishes entry and presses \gui OK, or when
the user presses Enter after finishing the other fields. Alternately,
include the field in the tab order but disable it. Enable it if it
becomes appropriate in view of what the user has set in the other
fields.
- \o The label for the field can include a keyboard shortcut that moves
+ \li The label for the field can include a keyboard shortcut that moves
focus to this field.
\endlist
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
index 313757ebec..a74cab0509 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
@@ -38,11 +38,11 @@
\table 100%
\row
-\o \image cde-checkbox.png
+\li \image cde-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image cde-radiobutton.png
+\li \image cde-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
-\o \image cde-pushbutton.png
+\li \image cde-pushbutton.png
\image cde-toolbutton.png
\caption The QPushButton widget provides a command button.
\endtable
@@ -51,13 +51,13 @@
\table 100%
\row
-\o \image cde-groupbox.png
+\li \image cde-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image cde-tabwidget.png
+\li \image cde-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image cde-frame.png
+\li \image cde-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image cde-toolbox.png
+\li \image cde-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -65,24 +65,24 @@
\table 100%
\row
-\o \image cde-listview.png
+\li \image cde-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image cde-treeview.png
+\li \image cde-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image cde-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image cde-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image cde-progressbar.png
+\li \image cde-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image cde-label.png
+\li \image cde-label.png
The QLabel widget provides a text or image display.
-\o \image cde-lcdnumber.png
+\li \image cde-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -90,43 +90,43 @@
\table 100%
\row
-\o \image cde-lineedit.png
+\li \image cde-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image cde-dateedit.png
+\li \image cde-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image cde-timeedit.png
+\li \image cde-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image cde-datetimeedit.png
+\li \image cde-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image cde-slider.png
+\li \image cde-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image cde-combobox.png
+\li \image cde-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image cde-spinbox.png
+\li \image cde-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image cde-fontcombobox.png
+\li \image cde-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image cde-doublespinbox.png
+\li \image cde-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image cde-horizontalscrollbar.png
+\li \image cde-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image cde-dial.png
+\li \image cde-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image cde-textedit.png
+\li \image cde-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image cde-calendarwidget.png
+\li \image cde-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
index 74cd4d4d42..bed6d0ca40 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image cleanlooks-pushbutton.png
+\li \image cleanlooks-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image cleanlooks-toolbutton.png
+\li \image cleanlooks-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image cleanlooks-checkbox.png
+\li \image cleanlooks-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image cleanlooks-radiobutton.png
+\li \image cleanlooks-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image cleanlooks-groupbox.png
+\li \image cleanlooks-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image cleanlooks-tabwidget.png
+\li \image cleanlooks-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image cleanlooks-frame.png
+\li \image cleanlooks-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image cleanlooks-toolbox.png
+\li \image cleanlooks-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image cleanlooks-listview.png
+\li \image cleanlooks-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image cleanlooks-treeview.png
+\li \image cleanlooks-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image cleanlooks-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image cleanlooks-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image cleanlooks-progressbar.png
+\li \image cleanlooks-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image cleanlooks-label.png
+\li \image cleanlooks-label.png
The QLabel widget provides a text or image display.
-\o \image cleanlooks-lcdnumber.png
+\li \image cleanlooks-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image cleanlooks-lineedit.png
+\li \image cleanlooks-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image cleanlooks-dateedit.png
+\li \image cleanlooks-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image cleanlooks-timeedit.png
+\li \image cleanlooks-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image cleanlooks-datetimeedit.png
+\li \image cleanlooks-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image cleanlooks-slider.png
+\li \image cleanlooks-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image cleanlooks-combobox.png
+\li \image cleanlooks-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image cleanlooks-spinbox.png
+\li \image cleanlooks-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image cleanlooks-fontcombobox.png
+\li \image cleanlooks-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image cleanlooks-doublespinbox.png
+\li \image cleanlooks-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image cleanlooks-horizontalscrollbar.png
+\li \image cleanlooks-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image cleanlooks-dial.png
+\li \image cleanlooks-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image cleanlooks-textedit.png
+\li \image cleanlooks-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image cleanlooks-calendarwidget.png
+\li \image cleanlooks-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
index 6a7fb5f3b5..820f0b4140 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
@@ -41,18 +41,18 @@
\table 100%
\row
-\o \image gtk-pushbutton.png
+\li \image gtk-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image gtk-toolbutton.png
+\li \image gtk-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image gtk-checkbox.png
+\li \image gtk-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image gtk-radiobutton.png
+\li \image gtk-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -60,13 +60,13 @@
\table 100%
\row
-\o \image gtk-groupbox.png
+\li \image gtk-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image gtk-tabwidget.png
+\li \image gtk-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image gtk-frame.png
+\li \image gtk-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image gtk-toolbox.png
+\li \image gtk-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -74,24 +74,24 @@
\table 100%
\row
-\o \image gtk-listview.png
+\li \image gtk-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image gtk-treeview.png
+\li \image gtk-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image gtk-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image gtk-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image gtk-progressbar.png
+\li \image gtk-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image gtk-label.png
+\li \image gtk-label.png
The QLabel widget provides a text or image display.
-\o \image gtk-lcdnumber.png
+\li \image gtk-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -99,43 +99,43 @@
\table 100%
\row
-\o \image gtk-lineedit.png
+\li \image gtk-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image gtk-dateedit.png
+\li \image gtk-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image gtk-timeedit.png
+\li \image gtk-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image gtk-datetimeedit.png
+\li \image gtk-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image gtk-slider.png
+\li \image gtk-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image gtk-combobox.png
+\li \image gtk-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image gtk-spinbox.png
+\li \image gtk-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image gtk-fontcombobox.png
+\li \image gtk-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image gtk-doublespinbox.png
+\li \image gtk-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image gtk-horizontalscrollbar.png
+\li \image gtk-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image gtk-dial.png
+\li \image gtk-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image gtk-textedit.png
+\li \image gtk-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image gtk-calendarwidget.png
+\li \image gtk-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
index 6eceea114f..488a3f7665 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image macintosh-pushbutton.png
+\li \image macintosh-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image macintosh-toolbutton.png
+\li \image macintosh-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image macintosh-checkbox.png
+\li \image macintosh-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image macintosh-radiobutton.png
+\li \image macintosh-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image macintosh-groupbox.png
+\li \image macintosh-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image macintosh-tabwidget.png
+\li \image macintosh-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image macintosh-frame.png
+\li \image macintosh-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image macintosh-toolbox.png
+\li \image macintosh-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image macintosh-listview.png
+\li \image macintosh-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image macintosh-treeview.png
+\li \image macintosh-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image macintosh-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image macintosh-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image macintosh-progressbar.png
+\li \image macintosh-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image macintosh-label.png
+\li \image macintosh-label.png
The QLabel widget provides a text or image display.
-\o \image macintosh-lcdnumber.png
+\li \image macintosh-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image macintosh-lineedit.png
+\li \image macintosh-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image macintosh-dateedit.png
+\li \image macintosh-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image macintosh-timeedit.png
+\li \image macintosh-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image macintosh-datetimeedit.png
+\li \image macintosh-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image macintosh-slider.png
+\li \image macintosh-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image macintosh-combobox.png
+\li \image macintosh-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image macintosh-spinbox.png
+\li \image macintosh-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image macintosh-fontcombobox.png
+\li \image macintosh-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image macintosh-doublespinbox.png
+\li \image macintosh-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image macintosh-horizontalscrollbar.png
+\li \image macintosh-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image macintosh-dial.png
+\li \image macintosh-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image macintosh-textedit.png
+\li \image macintosh-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image macintosh-calendarwidget.png
+\li \image macintosh-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
index d059d2282f..5cbffc5516 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image motif-pushbutton.png
+\li \image motif-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image motif-toolbutton.png
+\li \image motif-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image motif-checkbox.png
+\li \image motif-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image motif-radiobutton.png
+\li \image motif-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image motif-groupbox.png
+\li \image motif-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image motif-tabwidget.png
+\li \image motif-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image motif-frame.png
+\li \image motif-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image motif-toolbox.png
+\li \image motif-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image motif-listview.png
+\li \image motif-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image motif-treeview.png
+\li \image motif-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image motif-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image motif-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image motif-progressbar.png
+\li \image motif-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image motif-label.png
+\li \image motif-label.png
The QLabel widget provides a text or image display.
-\o \image motif-lcdnumber.png
+\li \image motif-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image motif-lineedit.png
+\li \image motif-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image motif-dateedit.png
+\li \image motif-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image motif-timeedit.png
+\li \image motif-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image motif-datetimeedit.png
+\li \image motif-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image motif-slider.png
+\li \image motif-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image motif-combobox.png
+\li \image motif-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image motif-spinbox.png
+\li \image motif-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image motif-fontcombobox.png
+\li \image motif-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image motif-doublespinbox.png
+\li \image motif-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image motif-horizontalscrollbar.png
+\li \image motif-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image motif-dial.png
+\li \image motif-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image motif-textedit.png
+\li \image motif-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image motif-calendarwidget.png
+\li \image motif-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
index 9a57bd6cbc..359fac8018 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image plastique-pushbutton.png
+\li \image plastique-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image plastique-toolbutton.png
+\li \image plastique-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image plastique-checkbox.png
+\li \image plastique-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image plastique-radiobutton.png
+\li \image plastique-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image plastique-groupbox.png
+\li \image plastique-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image plastique-tabwidget.png
+\li \image plastique-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image plastique-frame.png
+\li \image plastique-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image plastique-toolbox.png
+\li \image plastique-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image plastique-listview.png
+\li \image plastique-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image plastique-treeview.png
+\li \image plastique-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image plastique-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image plastique-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image plastique-progressbar.png
+\li \image plastique-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image plastique-label.png
+\li \image plastique-label.png
The QLabel widget provides a text or image display.
-\o \image plastique-lcdnumber.png
+\li \image plastique-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image plastique-lineedit.png
+\li \image plastique-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image plastique-dateedit.png
+\li \image plastique-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image plastique-timeedit.png
+\li \image plastique-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image plastique-datetimeedit.png
+\li \image plastique-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image plastique-slider.png
+\li \image plastique-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image plastique-combobox.png
+\li \image plastique-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image plastique-spinbox.png
+\li \image plastique-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image plastique-fontcombobox.png
+\li \image plastique-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image plastique-doublespinbox.png
+\li \image plastique-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image plastique-horizontalscrollbar.png
+\li \image plastique-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image plastique-dial.png
+\li \image plastique-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image plastique-textedit.png
+\li \image plastique-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image plastique-calendarwidget.png
+\li \image plastique-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
index 83ebce97f5..b118c845c6 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windows-pushbutton.png
+\li \image windows-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windows-toolbutton.png
+\li \image windows-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windows-checkbox.png
+\li \image windows-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windows-radiobutton.png
+\li \image windows-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windows-groupbox.png
+\li \image windows-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windows-tabwidget.png
+\li \image windows-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windows-frame.png
+\li \image windows-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windows-toolbox.png
+\li \image windows-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windows-listview.png
+\li \image windows-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windows-treeview.png
+\li \image windows-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windows-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windows-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windows-progressbar.png
+\li \image windows-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windows-label.png
+\li \image windows-label.png
The QLabel widget provides a text or image display.
-\o \image windows-lcdnumber.png
+\li \image windows-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windows-lineedit.png
+\li \image windows-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windows-dateedit.png
+\li \image windows-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windows-timeedit.png
+\li \image windows-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windows-datetimeedit.png
+\li \image windows-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windows-slider.png
+\li \image windows-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windows-combobox.png
+\li \image windows-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windows-spinbox.png
+\li \image windows-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windows-fontcombobox.png
+\li \image windows-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windows-doublespinbox.png
+\li \image windows-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windows-horizontalscrollbar.png
+\li \image windows-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windows-dial.png
+\li \image windows-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windows-textedit.png
+\li \image windows-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windows-calendarwidget.png
+\li \image windows-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
index e54a4dc399..db1a7cee90 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windowsvista-pushbutton.png
+\li \image windowsvista-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windowsvista-toolbutton.png
+\li \image windowsvista-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windowsvista-checkbox.png
+\li \image windowsvista-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windowsvista-radiobutton.png
+\li \image windowsvista-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windowsvista-groupbox.png
+\li \image windowsvista-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windowsvista-tabwidget.png
+\li \image windowsvista-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windowsvista-frame.png
+\li \image windowsvista-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windowsvista-toolbox.png
+\li \image windowsvista-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windowsvista-listview.png
+\li \image windowsvista-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windowsvista-treeview.png
+\li \image windowsvista-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windowsvista-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windowsvista-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windowsvista-progressbar.png
+\li \image windowsvista-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windowsvista-label.png
+\li \image windowsvista-label.png
The QLabel widget provides a text or image display.
-\o \image windowsvista-lcdnumber.png
+\li \image windowsvista-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windowsvista-lineedit.png
+\li \image windowsvista-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windowsvista-dateedit.png
+\li \image windowsvista-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windowsvista-timeedit.png
+\li \image windowsvista-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windowsvista-datetimeedit.png
+\li \image windowsvista-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windowsvista-slider.png
+\li \image windowsvista-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windowsvista-combobox.png
+\li \image windowsvista-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windowsvista-spinbox.png
+\li \image windowsvista-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windowsvista-fontcombobox.png
+\li \image windowsvista-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windowsvista-doublespinbox.png
+\li \image windowsvista-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windowsvista-horizontalscrollbar.png
+\li \image windowsvista-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windowsvista-dial.png
+\li \image windowsvista-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windowsvista-textedit.png
+\li \image windowsvista-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windowsvista-calendarwidget.png
+\li \image windowsvista-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
index 3753402c5a..2ade5681e2 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windowsxp-pushbutton.png
+\li \image windowsxp-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windowsxp-toolbutton.png
+\li \image windowsxp-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windowsxp-checkbox.png
+\li \image windowsxp-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windowsxp-radiobutton.png
+\li \image windowsxp-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windowsxp-groupbox.png
+\li \image windowsxp-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windowsxp-tabwidget.png
+\li \image windowsxp-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windowsxp-frame.png
+\li \image windowsxp-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windowsxp-toolbox.png
+\li \image windowsxp-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windowsxp-listview.png
+\li \image windowsxp-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windowsxp-treeview.png
+\li \image windowsxp-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windowsxp-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windowsxp-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windowsxp-progressbar.png
+\li \image windowsxp-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windowsxp-label.png
+\li \image windowsxp-label.png
The QLabel widget provides a text or image display.
-\o \image windowsxp-lcdnumber.png
+\li \image windowsxp-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windowsxp-lineedit.png
+\li \image windowsxp-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windowsxp-dateedit.png
+\li \image windowsxp-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windowsxp-timeedit.png
+\li \image windowsxp-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windowsxp-datetimeedit.png
+\li \image windowsxp-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windowsxp-slider.png
+\li \image windowsxp-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windowsxp-combobox.png
+\li \image windowsxp-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windowsxp-spinbox.png
+\li \image windowsxp-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windowsxp-fontcombobox.png
+\li \image windowsxp-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windowsxp-doublespinbox.png
+\li \image windowsxp-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windowsxp-horizontalscrollbar.png
+\li \image windowsxp-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windowsxp-dial.png
+\li \image windowsxp-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windowsxp-textedit.png
+\li \image windowsxp-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windowsxp-calendarwidget.png
+\li \image windowsxp-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery.qdoc b/doc/src/widgets/widgets-and-layouts/gallery.qdoc
index d82eda4805..a2f4db5a7b 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery.qdoc
@@ -36,15 +36,15 @@
\table
\row
- \o \image plastique-tabwidget.png Plastique Style Widget Gallery
+ \li \image plastique-tabwidget.png Plastique Style Widget Gallery
\caption \l{Plastique Style Widget Gallery}
The Plastique style is provided by QPlastiqueStyle.
- \o \image windowsxp-tabwidget.png Windows XP Style Widget Gallery
+ \li \image windowsxp-tabwidget.png Windows XP Style Widget Gallery
\caption \l{Windows XP Style Widget Gallery}
The Windows XP style is provided by QWindowsXPStyle.
- \o \image windows-tabwidget.png Windows Style Widget Gallery
+ \li \image windows-tabwidget.png Windows Style Widget Gallery
\caption \l{Windows Style Widget Gallery}
The Windows style is provided by QWindowsStyle.
@@ -52,15 +52,15 @@
\table
\row
- \o \image macintosh-tabwidget.png Macintosh Style Widget Gallery
+ \li \image macintosh-tabwidget.png Macintosh Style Widget Gallery
\caption \l{Macintosh Style Widget Gallery}
The Macintosh style is provided by QMacStyle.
- \o \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery
+ \li \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery
\caption \l{Cleanlooks Style Widget Gallery}
The Cleanlooks style is provided by QCleanlooksStyle.
- \o \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery
+ \li \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery
\caption \l{Windows Vista Style Widget Gallery}
The Windows Vista style is provided by QWindowsVistaStyle.
@@ -68,15 +68,15 @@
\table
\row
- \o \image gtk-tabwidget.png GTK Style Widget Gallery
+ \li \image gtk-tabwidget.png GTK Style Widget Gallery
\caption \l{GTK Style Widget Gallery}
The GTK style is provided by QGtkStyle.
- \o \image motif-tabwidget.png Motif Style Widget Gallery
+ \li \image motif-tabwidget.png Motif Style Widget Gallery
\caption \l{Motif Style Widget Gallery}
The Motif style is provided by QMotifStyle.
- \o \image cde-tabwidget.png CDE Style Widget Gallery
+ \li \image cde-tabwidget.png CDE Style Widget Gallery
\caption \l{CDE Style Widget Gallery}
The Common Desktop Environment style is provided by QCDEStyle.
diff --git a/doc/src/widgets/widgets-and-layouts/layout.qdoc b/doc/src/widgets/widgets-and-layouts/layout.qdoc
index ccc15ef805..6e1a5f70e1 100644
--- a/doc/src/widgets/widgets-and-layouts/layout.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/layout.qdoc
@@ -63,15 +63,15 @@
is set on a widget in this way, it takes charge of the following tasks:
\list
- \o Positioning of child widgets.
- \o Sensible default sizes for windows.
- \o Sensible minimum sizes for windows.
- \o Resize handling.
- \o Automatic updates when contents change:
+ \li Positioning of child widgets.
+ \li Sensible default sizes for windows.
+ \li Sensible minimum sizes for windows.
+ \li Resize handling.
+ \li Automatic updates when contents change:
\list
- \o Font size, text or other contents of child widgets.
- \o Hiding or showing a child widget.
- \o Removal of child widgets.
+ \li Font size, text or other contents of child widgets.
+ \li Hiding or showing a child widget.
+ \li Removal of child widgets.
\endlist
\endlist
@@ -95,19 +95,19 @@
create more complex layouts, you can nest layout managers inside each other.
\list
- \o A QHBoxLayout lays out widgets in a horizontal row, from left to
+ \li A QHBoxLayout lays out widgets in a horizontal row, from left to
right (or right to left for right-to-left languages).
\image qhboxlayout-with-5-children.png
- \o A QVBoxLayout lays out widgets in a vertical column, from top to
+ \li A QVBoxLayout lays out widgets in a vertical column, from top to
bottom.
\image qvboxlayout-with-5-children.png
- \o A QGridLayout lays out widgets in a two-dimensional grid. Widgets
+ \li A QGridLayout lays out widgets in a two-dimensional grid. Widgets
can occupy multiple cells.
\image qgridlayout-with-5-children.png
- \o A QFormLayout lays out widgets in a 2-column descriptive label-
+ \li A QFormLayout lays out widgets in a 2-column descriptive label-
field style.
\image qformlayout-with-6-children.png
\endlist
@@ -176,26 +176,26 @@
When you add widgets to a layout, the layout process works as follows:
\list 1
- \o All the widgets will initially be allocated an amount of space in
+ \li All the widgets will initially be allocated an amount of space in
accordance with their QWidget::sizePolicy() and
QWidget::sizeHint().
- \o If any of the widgets have stretch factors set, with a value
+ \li If any of the widgets have stretch factors set, with a value
greater than zero, then they are allocated space in proportion to
their stretch factor (explained below).
- \o If any of the widgets have stretch factors set to zero they will
+ \li If any of the widgets have stretch factors set to zero they will
only get more space if no other widgets want the space. Of these,
space is allocated to widgets with an
\l{QSizePolicy::Expanding}{Expanding} size policy first.
- \o Any widgets that are allocated less space than their minimum size
+ \li Any widgets that are allocated less space than their minimum size
(or minimum size hint if no minimum size is specified) are
allocated this minimum size they require. (Widgets don't have to
have a minimum size or minimum size hint in which case the stretch
factor is their determining factor.)
- \o Any widgets that are allocated more space than their maximum size
+ \li Any widgets that are allocated more space than their maximum size
are allocated the maximum size space they require. (Widgets do not
have to have a maximum size in which case the stretch factor is
their determining factor.)
@@ -231,11 +231,11 @@
following mechanisms:
\list
- \o Reimplement QWidget::sizeHint() to return the preferred size of the
+ \li Reimplement QWidget::sizeHint() to return the preferred size of the
widget.
- \o Reimplement QWidget::minimumSizeHint() to return the smallest size
+ \li Reimplement QWidget::minimumSizeHint() to return the smallest size
the widget can have.
- \o Call QWidget::setSizePolicy() to specify the space requirements of
+ \li Call QWidget::setSizePolicy() to specify the space requirements of
the widget.
\endlist
@@ -304,14 +304,14 @@
To write your own layout class, you must define the following:
\list
- \o A data structure to store the items handled by the layout. Each
+ \li A data structure to store the items handled by the layout. Each
item is a \link QLayoutItem QLayoutItem\endlink. We will use a
QList in this example.
- \o \l{QLayout::}{addItem()}, how to add items to the layout.
- \o \l{QLayout::}{setGeometry()}, how to perform the layout.
- \o \l{QLayout::}{sizeHint()}, the preferred size of the layout.
- \o \l{QLayout::}{itemAt()}, how to iterate over the layout.
- \o \l{QLayout::}{takeAt()}, how to remove items from the layout.
+ \li \l{QLayout::}{addItem()}, how to add items to the layout.
+ \li \l{QLayout::}{setGeometry()}, how to perform the layout.
+ \li \l{QLayout::}{sizeHint()}, the preferred size of the layout.
+ \li \l{QLayout::}{itemAt()}, how to iterate over the layout.
+ \li \l{QLayout::}{takeAt()}, how to remove items from the layout.
\endlist
In most cases, you will also implement \l{QLayout::}{minimumSize()}.
@@ -376,16 +376,16 @@
\section2 Further Notes
\list
- \o This custom layout does not handle height for width.
- \o We ignore QLayoutItem::isEmpty(); this means that the layout will
+ \li This custom layout does not handle height for width.
+ \li We ignore QLayoutItem::isEmpty(); this means that the layout will
treat hidden widgets as visible.
- \o For complex layouts, speed can be greatly increased by caching
+ \li For complex layouts, speed can be greatly increased by caching
calculated values. In that case, implement
QLayoutItem::invalidate() to mark the cached data is dirty.
- \o Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
+ \li Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
should store the value in a local variable if you need it again
later within in the same function.
- \o You should not call QLayoutItem::setGeometry() twice on the same
+ \li You should not call QLayoutItem::setGeometry() twice on the same
item in the same function. This call can be very expensive if the
item has several child widgets, because the layout manager must do
a complete layout every time. Instead, calculate the geometry and
diff --git a/doc/src/widgets/widgets-and-layouts/styles.qdoc b/doc/src/widgets/widgets-and-layouts/styles.qdoc
index febe1a8345..b9e3a30333 100644
--- a/doc/src/widgets/widgets-and-layouts/styles.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/styles.qdoc
@@ -93,10 +93,10 @@
bar. Most draw functions now take four arguments:
\list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption specifying how and where to render that element
- \o a QPainter that should be used to draw the element
- \o a QWidget on which the drawing is performed (optional)
+ \li an enum value specifying which graphical element to draw
+ \li a QStyleOption specifying how and where to render that element
+ \li a QPainter that should be used to draw the element
+ \li a QWidget on which the drawing is performed (optional)
\endlist
When a widget asks a style to draw an element, it provides the style
@@ -309,11 +309,11 @@
following parameters:
\list
- \o the enum value of the element to draw
- \o a QStyleOption which contains the information needed to
+ \li the enum value of the element to draw
+ \li a QStyleOption which contains the information needed to
draw the element.
- \o a QPainter with which to draw the element.
- \o a pointer to a QWidget, typically the widget
+ \li a QPainter with which to draw the element.
+ \li a pointer to a QWidget, typically the widget
that the element is painted on.
\endlist
@@ -337,27 +337,27 @@
typically takes the same arguments.
\list
- \o The \l{QStyle::}{subElementRect()} function takes a
+ \li The \l{QStyle::}{subElementRect()} function takes a
\l{QStyle::}{SubElement} enum value, and calculates a bounding
rectangle for a sub element. The style uses this function to
know where to draw the different parts of an element. This is
mainly done for reuse. If you create a new style, you can use
the same location of sub elements as the super class.
- \o The \l{QStyle::}{subControlRect()} function is used to
+ \li The \l{QStyle::}{subControlRect()} function is used to
calculate bounding rectangles for sub controls in complex
controls. When you implement a new style, you reimplement \c
subControlRect() and calculate the rectangles that are different
from the super class.
- \o The \l{QStyle::}{pixelMetric()} function returns a pixel
+ \li The \l{QStyle::}{pixelMetric()} function returns a pixel
metric, which is a style dependent size given in screen
pixels. It takes a value of the \l{QStyle::}{PixelMetric} enum
and returns the correct measure. Note that pixel metrics do
not necessarily have to be static measures, but can be
calculated with, for example, the style option.
- \o The \l{QStyle::}{hitTestComplexControl()} function returns the
+ \li The \l{QStyle::}{hitTestComplexControl()} function returns the
sub control that the mouse pointer is over in a complex control.
Usually, this is simply a matter of using
\l{QStyle::}{subControlRect()} to get the bounding rectangles of
@@ -588,35 +588,35 @@
\table 90%
\header
- \o State flag
- \o Set
+ \li State flag
+ \li Set
\row
- \o State_Sunken
- \o Yes
+ \li State_Sunken
+ \li Yes
\row
- \o State_NoChange
- \o No
+ \li State_NoChange
+ \li No
\row
- \o State_On
- \o Yes
+ \li State_On
+ \li Yes
\row
- \o State_Off
- \o No
+ \li State_Off
+ \li No
\row
- \o State_MouseOver
- \o Yes
+ \li State_MouseOver
+ \li Yes
\row
- \o State_Enabled
- \o Yes
+ \li State_Enabled
+ \li Yes
\row
- \o State_HasFocus
- \o Yes
+ \li State_HasFocus
+ \li Yes
\row
- \o State_KeyboardFocusChange
- \o No
+ \li State_KeyboardFocusChange
+ \li No
\row
- \o State_Active
- \o Yes
+ \li State_Active
+ \li Yes
\endtable
The QCheckBox paints itself in QWidget::paintEvent() with
@@ -714,16 +714,16 @@
The following is given for each widget:
\list
- \o A table with the members (variables, etc.) of its style option.
- \o A table over the state flags (QStyle::StateFlag) that
+ \li A table with the members (variables, etc.) of its style option.
+ \li A table over the state flags (QStyle::StateFlag) that
can be set on the widget and when the states are set.
- \o Its element tree (see section \l{The Style Elements}).
- \o An image of the widget in which the elements are outlined.
+ \li Its element tree (see section \l{The Style Elements}).
+ \li An image of the widget in which the elements are outlined.
\omit This is not written yet - probably never will be
either
- \o List of style hints that should be checked for the
+ \li List of style hints that should be checked for the
widget.
- \o List of standard pixmaps that could be used by the
+ \li List of standard pixmaps that could be used by the
elements.
\endomit
\endlist
@@ -737,7 +737,7 @@
Our approach on styling center on the drawing of the widgets. The
calculations of sub elements rectangles, sub controls, and pixel
- metrics used \bold during drawing is only listed as contents in
+ metrics used \b during drawing is only listed as contents in
the element trees. Note that there are rectangles and pixel
metrics that are only used by widgets. This leaves these
calculations untreated in the walkthrough. For instance, the
@@ -778,53 +778,53 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Enabled
- \o Set if the widget is not disabled (see
+ \li State_Enabled
+ \li Set if the widget is not disabled (see
QWidget::setEnabled())
\row
- \o State_Focus
- \o Set if the widget has focus (see
+ \li State_Focus
+ \li Set if the widget has focus (see
QWidget::hasFocus())
\row
- \o State_KeyobordFocusChange
- \o Set when the user changes focus with the keyboard
+ \li State_KeyobordFocusChange
+ \li Set when the user changes focus with the keyboard
(see Qt::WA_KeyboardFocusChange)
\row
- \o State_MouseOver
- \o Set if the mouse cursor is over the widget
+ \li State_MouseOver
+ \li Set if the mouse cursor is over the widget
\row
- \o State_Active
- \o Set if the widget is a child of the active window.
+ \li State_Active
+ \li Set if the widget is a child of the active window.
\row
- \o State_HasEditFocus
- \o Set if the widget has the edit focus
+ \li State_HasEditFocus
+ \li Set if the widget has the edit focus
\endtable
The other common members for widgets are:
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o rect
- \o The bounding rectangle of the element to draw. This
+ \li rect
+ \li The bounding rectangle of the element to draw. This
is set to the widget bounding rectangle
(QWidget::rect()).
\row
- \o direction
- \o The layout direction; a value of the
+ \li direction
+ \li The layout direction; a value of the
Qt::LayoutDirection enum.
\row
- \o palette
- \o The QPalette to use when drawing the element. This
+ \li palette
+ \li The QPalette to use when drawing the element. This
is set to the widgets palette (QWidget::palette()).
\row
- \o fontMetrics
- \o The QFontMetrics to use when drawing text on the
+ \li fontMetrics
+ \li The QFontMetrics to use when drawing text on the
widget.
\endtable
@@ -885,38 +885,38 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o Button is down or menu is pressed shown
+ \li State_Sunken
+ \li Button is down or menu is pressed shown
\row
- \o State_On
- \o Button is checked
+ \li State_On
+ \li Button is checked
\row
- \o State_Raised
- \o Button is not flat and not pressed down
+ \li State_Raised
+ \li Button is not flat and not pressed down
\endtable
Other members of QStyleOptionButton is:
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o Flags of the QStyleOptionButton::ButtonFeatures enum,
+ \li features
+ \li Flags of the QStyleOptionButton::ButtonFeatures enum,
which describes various button properties (see enum)
\row
- \o icon
- \o The buttons QIcon (if any)
+ \li icon
+ \li The buttons QIcon (if any)
\row
- \o iconSize
- \o The QSize of the icon
+ \li iconSize
+ \li The QSize of the icon
\row
- \o text
- \o a QString with the buttons text
+ \li text
+ \li a QString with the buttons text
\endtable
\section3 Check and Radio Buttons
@@ -933,21 +933,21 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_sunken
- \o The box is pressed down
+ \li State_sunken
+ \li The box is pressed down
\row
- \o State_NoChange
- \o The box is partially checked (for tristate
+ \li State_NoChange
+ \li The box is partially checked (for tristate
checkboxes.)
\row
- \o State_On
- \o The box is checked
+ \li State_On
+ \li The box is checked
\row
- \o State_Off
- \o The box is unchecked
+ \li State_Off
+ \li The box is unchecked
\endtable
See \l{Push Buttons} for a table over other members in the
@@ -1017,17 +1017,17 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o The tab is pressed on with the mouse.
+ \li State_Sunken
+ \li The tab is pressed on with the mouse.
\row
- \o State_Selected
- \o If it is the current tab.
+ \li State_Selected
+ \li If it is the current tab.
\row
- \o State_HasFocus
- \o The tab bar has focus and the tab is selected
+ \li State_HasFocus
+ \li The tab bar has focus and the tab is selected
\endtable
Note that individual tabs may be disabled even if the tab bar
@@ -1037,38 +1037,38 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o cornerWidgets
- \o Is flags of the CornerWidget enum, which indicate
+ \li cornerWidgets
+ \li Is flags of the CornerWidget enum, which indicate
if and which corner widgets the tab bar has.
\row
- \o icon
- \o The QIcon of the tab
+ \li icon
+ \li The QIcon of the tab
\row
- \o iconSize
- \o The QSize of the icon
+ \li iconSize
+ \li The QSize of the icon
\row
- \o position
- \o A TabPosition enum value that indicates the tabs
+ \li position
+ \li A TabPosition enum value that indicates the tabs
position on the bar relative to the other tabs.
\row
- \o row
- \o holds which row the tab is in
+ \li row
+ \li holds which row the tab is in
\row
- \o selectedPosition
- \o A value of the SelectedPosition enum that indicates
+ \li selectedPosition
+ \li A value of the SelectedPosition enum that indicates
whether the selected tab is adjacent to or is the
tab.
\row
- \o shape
- \o A value of the QTabBar::Shape enum indication
+ \li shape
+ \li A value of the QTabBar::Shape enum indication
whether the tab has rounded or triangular corners
and the orientation of the tab.
\row
- \o text
- \o The tab text
+ \li text
+ \li The tab text
\endtable
The frame for tab widgets use QStyleOptionTabWidgetFrame as
@@ -1077,26 +1077,26 @@
\table 90%
\header
- \o Member
- \o content
+ \li Member
+ \li content
\row
- \o leftCornerWidgetSize
- \o The QSize of the left corner widget (if any).
+ \li leftCornerWidgetSize
+ \li The QSize of the left corner widget (if any).
\row
- \o rightCornerWidgetSize
- \o The QSize of the right corner widget (if any).
+ \li rightCornerWidgetSize
+ \li The QSize of the right corner widget (if any).
\row
- \o lineWidth
- \o holds the line with for drawing the panel.
+ \li lineWidth
+ \li holds the line with for drawing the panel.
\row
- \o midLineWith
- \o this value is currently always 0.
+ \li midLineWith
+ \li this value is currently always 0.
\row
- \o shape
- \o The shape of the tabs on the tab bar.
+ \li shape
+ \li The shape of the tabs on the tab bar.
\row
- \o tabBarSize
- \o The QSize of the tab bar.
+ \li tabBarSize
+ \li The QSize of the tab bar.
\endtable
\section3 Scroll Bars
@@ -1130,11 +1130,11 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Horizontal
- \o The scroll bar is horizontal
+ \li State_Horizontal
+ \li The scroll bar is horizontal
\endtable
The style option of QScrollBar is QStyleOptionSlider. Its
@@ -1144,43 +1144,43 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o maximum
- \o the maximum value of the scroll bar
+ \li maximum
+ \li the maximum value of the scroll bar
\row
- \o minimum
- \o the minimum value of the scroll bar
+ \li minimum
+ \li the minimum value of the scroll bar
\row
- \o notchTarget
- \o the number of pixels between notches
+ \li notchTarget
+ \li the number of pixels between notches
\row
- \o orientation
- \o a value of the Qt::Orientation enum that specifies
+ \li orientation
+ \li a value of the Qt::Orientation enum that specifies
whether the scroll bar is vertical or horizontal
\row
- \o pageStep
- \o the number to increase or decrease the sliders
+ \li pageStep
+ \li the number to increase or decrease the sliders
value (relative to the size of the slider and its value
range) on page steps.
\row
- \o singleStep
- \o the number to increase or decrease the sliders
+ \li singleStep
+ \li the number to increase or decrease the sliders
value on single (or line) steps
\row
- \o sliderValue
- \o The value of the slider
+ \li sliderValue
+ \li The value of the slider
\row
- \o sliderPosition
- \o the position of the slider handle. This is the same
+ \li sliderPosition
+ \li the position of the slider handle. This is the same
as \c sliderValue if the scroll bar is
QAbstractSlider::tracking. If not, the scroll
bar does not update its value before the mouse
releases the handle.
\row
- \o upsideDown
- \o holds the direction in which the scroll bar
+ \li upsideDown
+ \li holds the direction in which the scroll bar
increases its value. This is used instead of
QStyleOption::direction for all abstract sliders.
\endtable
@@ -1207,42 +1207,42 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o maximum
- \o the maximum value of the slider
+ \li maximum
+ \li the maximum value of the slider
\row
- \o minimum
- \o the minimum value of the slider
+ \li minimum
+ \li the minimum value of the slider
\row
- \o notchTarget
- \o this is the number of pixels between each notch
+ \li notchTarget
+ \li this is the number of pixels between each notch
\row
- \o orientation
- \o a Qt::Orientation enum value that gives whether the
+ \li orientation
+ \li a Qt::Orientation enum value that gives whether the
slider is vertical or horizontal.
\row
- \o pageStep
- \o a number in slider value to increase or decrease
+ \li pageStep
+ \li a number in slider value to increase or decrease
for page steps
\row
- \o singleStep
- \o the number to increase or decrease the sliders
+ \li singleStep
+ \li the number to increase or decrease the sliders
value on single (or line) steps.
\row
- \o sliderValue
- \o the value of the slider.
+ \li sliderValue
+ \li the value of the slider.
\row
- \o sliderPosition
- \o the position of the slider given as a slider value.
+ \li sliderPosition
+ \li the position of the slider given as a slider value.
This will be equal to the \c sliderValue if the
slider is \l{QAbstractSlider::}{tracking}; if
not, the sliders value will not change until the handle is
released with the mouse.
\row
- \o upsideDown
- \o this member is used instead of QStyleOption::direction
+ \li upsideDown
+ \li this member is used instead of QStyleOption::direction
for all abstract sliders.
\endtable
@@ -1270,11 +1270,11 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o Is set if one of the sub controls CC_SpinUp or
+ \li State_Sunken
+ \li Is set if one of the sub controls CC_SpinUp or
CC_SpinDown is pressed on with the mouse.
\endtable
@@ -1282,19 +1282,19 @@
\table 90%
\header
- \o Property
- \o Function
+ \li Property
+ \li Function
\row
- \o frame
- \o boolean that is true if the spin box is to draw a
+ \li frame
+ \li boolean that is true if the spin box is to draw a
frame.
\row
- \o buttonSymbols
- \o Value of the ButtonSymbols enum that decides the
+ \li buttonSymbols
+ \li Value of the ButtonSymbols enum that decides the
symbol on the up/down buttons.
\row
- \o stepEnabled
- \o A value of the StepEnabled indication which of the
+ \li stepEnabled
+ \li A value of the StepEnabled indication which of the
spin box buttons are pressed down.
\endtable
@@ -1326,21 +1326,21 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o The title bars icon
+ \li icon
+ \li The title bars icon
\row
- \o text
- \o the text for the title bar's label
+ \li text
+ \li the text for the title bar's label
\row
- \o windowFlags
- \o flags of the Qt::WindowFlag enum. The window flags
+ \li windowFlags
+ \li flags of the Qt::WindowFlag enum. The window flags
used by QMdiArea for window management.
\row
- \o titleBarState
- \o this is the QWidget::windowState() of the window
+ \li titleBarState
+ \li this is the QWidget::windowState() of the window
that contains the title bar.
\endtable
@@ -1374,44 +1374,44 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Selected
- \o The box is not editable and has focus
+ \li State_Selected
+ \li The box is not editable and has focus
\row
- \o State_Sunken
- \o SC_ComboBoxArrow is active
+ \li State_Sunken
+ \li SC_ComboBoxArrow is active
\row
- \o State_on
- \o The container (list) of the box is visible
+ \li State_on
+ \li The container (list) of the box is visible
\endtable
The style options other members are:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o currentIcon
- \o the icon of the current (selected) item of the
+ \li currentIcon
+ \li the icon of the current (selected) item of the
combo box.
\row
- \o currentText
- \o the text of the current item in the box.
+ \li currentText
+ \li the text of the current item in the box.
\row
- \o editable
- \o holds whether the combo box is editable or not
+ \li editable
+ \li holds whether the combo box is editable or not
\row
- \o frame
- \o holds whether the combo box has a frame or not
+ \li frame
+ \li holds whether the combo box has a frame or not
\row
- \o iconSize
- \o the size of the current items icon.
+ \li iconSize
+ \li the size of the current items icon.
\row
- \o popupRect
- \o the bounding rectangle of the combo box's popup
+ \li popupRect
+ \li the bounding rectangle of the combo box's popup
list.
\endtable
@@ -1438,42 +1438,42 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_On
- \o The check box is checked
+ \li State_On
+ \li The check box is checked
\row
- \o State_Sunken
- \o The checkbox is pressed down
+ \li State_Sunken
+ \li The checkbox is pressed down
\row
- \o State_Off
- \o The check box is unchecked (or there is no check box)
+ \li State_Off
+ \li The check box is unchecked (or there is no check box)
\endtable
The remaining members of QStyleOptionGroupBox are:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o flags of the QStyleOptionFrameV2::FrameFeatures
+ \li features
+ \li flags of the QStyleOptionFrameV2::FrameFeatures
enum describing the frame of the group box.
\row
- \o lineWidth
- \o the line width with which to draw the panel. This
+ \li lineWidth
+ \li the line width with which to draw the panel. This
is always 1.
\row
- \o text
- \o the text of the group box.
+ \li text
+ \li the text of the group box.
\row
- \o textAlignment
- \o the alignment of the group box title
+ \li textAlignment
+ \li the alignment of the group box title
\row
- \o textColor
- \o the QColor of the text
+ \li textColor
+ \li the QColor of the text
\endtable
\section3 Splitters
@@ -1487,11 +1487,11 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Horizontal
- \o Set if it is a horizontal splitter
+ \li State_Horizontal
+ \li Set if it is a horizontal splitter
\endtable
QSplitter does not use \l{QStyleOption::}{initFrom()} to set up its
@@ -1517,36 +1517,36 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o minimum
- \o The minimum value of the bar
+ \li minimum
+ \li The minimum value of the bar
\row
- \o maximum
- \o The maximum value of the bar
+ \li maximum
+ \li The maximum value of the bar
\row
- \o progress
- \o The current value of the bar
+ \li progress
+ \li The current value of the bar
\row
- \o textAlignment
- \o How the text is aligned in the label
+ \li textAlignment
+ \li How the text is aligned in the label
\row
- \o textVisible
- \o Whether the label is drawn
+ \li textVisible
+ \li Whether the label is drawn
\row
- \o text
- \o The label text
+ \li text
+ \li The label text
\row
- \o orientation
- \o Progress bars can be vertical or horizontal
+ \li orientation
+ \li Progress bars can be vertical or horizontal
\row
- \o invertedAppearance
- \o The progress is inverted (i.e., right to left in a
+ \li invertedAppearance
+ \li The progress is inverted (i.e., right to left in a
horizontal bar)
\row
- \o bottomToTop
- \o Boolean that if true, turns the label of vertical
+ \li bottomToTop
+ \li Boolean that if true, turns the label of vertical
progress bars 90 degrees.
\endtable
@@ -1578,58 +1578,58 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_AutoRise
- \o the tool button has the autoRise property set
+ \li State_AutoRise
+ \li the tool button has the autoRise property set
\row
- \o State_raised
- \o the button is not sunken (i.e., by being checked or
+ \li State_raised
+ \li the button is not sunken (i.e., by being checked or
pressed on with the mouse).
\row
- \o State_Sunken
- \o the button is down
+ \li State_Sunken
+ \li the button is down
\row
- \o State_On
- \o the button is checkable and checked.
+ \li State_On
+ \li the button is checkable and checked.
\endtable
QStyleOptionToolButton also contains the following members:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o arrowType
- \o a Qt::ArrowType enum value, which contains the
+ \li arrowType
+ \li a Qt::ArrowType enum value, which contains the
direction of the buttons arrow (if an arrow is to
be used in place of an icon)
\row
- \o features
- \o flags of the QStyleOptionToolButton::ButtonFeature
+ \li features
+ \li flags of the QStyleOptionToolButton::ButtonFeature
enum describing if the button has an arrow, a menu,
and/or has a popup-delay.
\row
- \o font
- \o the QFont of the buttons label
+ \li font
+ \li the QFont of the buttons label
\row
- \o icon
- \o the QIcon of the tool button
+ \li icon
+ \li the QIcon of the tool button
\row
- \o iconSize
- \o the icon size of the button's icon
+ \li iconSize
+ \li the icon size of the button's icon
\row
- \o pos
- \o the position of the button, as given by
+ \li pos
+ \li the position of the button, as given by
QWidget::pos()
\row
- \o text
- \o the text of the button
+ \li text
+ \li the text of the button
\row
- \o toolButtonStyle
- \o a Qt::ToolButtonStyle enum value which decides
+ \li toolButtonStyle
+ \li a Qt::ToolButtonStyle enum value which decides
whether the button shows the icon, the text, or both.
\endtable
@@ -1677,29 +1677,29 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o Holds whether the bar is movable in a value of the
+ \li features
+ \li Holds whether the bar is movable in a value of the
ToolBarFeature, which is either Movable or None.
\row
- \o lineWidth
- \o The width of the tool bar frame.
+ \li lineWidth
+ \li The width of the tool bar frame.
\row
- \o midLineWidth
- \o This variable is currently not used and is always
+ \li midLineWidth
+ \li This variable is currently not used and is always
0.
\row
- \o positionOfLine
- \o The position of the toolbar line within the toolbar
+ \li positionOfLine
+ \li The position of the toolbar line within the toolbar
area to which it belongs.
\row
- \o positionWithinLine
- \o The position of the toolbar within the toolbar line.
+ \li positionWithinLine
+ \li The position of the toolbar within the toolbar line.
\row
- \o toolBarArea
- \o The toolbar area in which the toolbar lives.
+ \li toolBarArea
+ \li The toolbar area in which the toolbar lives.
\endtable
\section3 Menus
@@ -1740,61 +1740,61 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Selected
- \o The mouse is over the action and the action is not
+ \li State_Selected
+ \li The mouse is over the action and the action is not
a separator.
\row
- \o State_Sunken
- \o The mouse is pressed down on the menu item.
+ \li State_Sunken
+ \li The mouse is pressed down on the menu item.
\row
- \o State_DownArrow
- \o Set if the menu item is a menu scroller and it scrolls
+ \li State_DownArrow
+ \li Set if the menu item is a menu scroller and it scrolls
the menu downwards.
\endtable
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o checkType
- \o A value of the \l{QStyleOptionMenuItem::}{CheckType} enum,
+ \li checkType
+ \li A value of the \l{QStyleOptionMenuItem::}{CheckType} enum,
which is either NotCheckable, Exclusive, or
NonExclusive.
\row
- \o checked
- \o Boolean that is true if the menu item is checked.
+ \li checked
+ \li Boolean that is true if the menu item is checked.
\row
- \o font
- \o The QFont to use for the menu item's text.
+ \li font
+ \li The QFont to use for the menu item's text.
\row
- \o icon
- \o the QIcon of the menu item.
+ \li icon
+ \li the QIcon of the menu item.
\row
- \o maxIconWidth
- \o The maximum width allowed for the icon
+ \li maxIconWidth
+ \li The maximum width allowed for the icon
\row
- \o menuHasChecableItem
- \o Boolean which is true if at least one item in the
+ \li menuHasChecableItem
+ \li Boolean which is true if at least one item in the
menu is checkable.
\row
- \o menuItemType
- \o The type of the menu item. This a value of the
+ \li menuItemType
+ \li The type of the menu item. This a value of the
\l{QStyleOptionMenuItem::}{MenuItemType}.
\row
- \o menuRect
- \o The bounding rectangle for the QMenu that the menu
+ \li menuRect
+ \li The bounding rectangle for the QMenu that the menu
item lives in.
\row
- \o tabWidth
- \o This is the distance between the text of the menu
+ \li tabWidth
+ \li This is the distance between the text of the menu
item and the shortcut.
\row
- \o text
- \o The text of the menu item.
+ \li text
+ \li The text of the menu item.
\endtable
The setup of the style option for CE_MenuTearOff and
@@ -1825,18 +1825,18 @@
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o menuRect
- \o the bounding rectangle of the entire menu bar to
+ \li menuRect
+ \li the bounding rectangle of the entire menu bar to
which the item belongs.
\row
- \o text
- \o the text of the item
+ \li text
+ \li the text of the item
\row
- \o icon
- \o the icon of the menu item (it is not common that
+ \li icon
+ \li the icon of the menu item (it is not common that
styles draw this icon)
\endtable
@@ -1874,44 +1874,44 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o the icon of the header (for section that is being
+ \li icon
+ \li the icon of the header (for section that is being
drawn).
\row
- \o iconAlignment
- \o the alignment (Qt::Alignment) of the icon in the header.
+ \li iconAlignment
+ \li the alignment (Qt::Alignment) of the icon in the header.
\row
- \o orientation
- \o a Qt::Orientation value deciding whether the header
+ \li orientation
+ \li a Qt::Orientation value deciding whether the header
is the horizontal header above the view or the
vertical header on the left.
\row
- \o position
- \o a QStyleOptionHeader::SectionPosition value
+ \li position
+ \li a QStyleOptionHeader::SectionPosition value
giving the header section's position relative to
the other sections.
\row
- \o section
- \o holds the section that is being drawn.
+ \li section
+ \li holds the section that is being drawn.
\row
- \o selectedPosition
- \o a QStyleOptionHeader::SelectedPosition value giving
+ \li selectedPosition
+ \li a QStyleOptionHeader::SelectedPosition value giving
the selected section's position relative to the
section that is being painted.
\row
- \o sortIndicator
- \o a QStyleOptionHeader::SortIndicator value that
+ \li sortIndicator
+ \li a QStyleOptionHeader::SortIndicator value that
describes the direction in which the section's sort
indicator should be drawn.
\row
- \o text
- \o the text of the currently drawn section.
+ \li text
+ \li the text of the currently drawn section.
\row
- \o textAlignment
- \o the Qt::Alignment of the text within the
+ \li textAlignment
+ \li the Qt::Alignment of the text within the
headersection.
\endtable
@@ -1927,22 +1927,22 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Sibling
- \o the node in the tree has a sibling (i.e., there is
+ \li State_Sibling
+ \li the node in the tree has a sibling (i.e., there is
another node in the same column).
\row
- \o State_Item
- \o this branch indicator has an item.
+ \li State_Item
+ \li this branch indicator has an item.
\row
- \o State_Children
- \o the branch has children (i.e., a new sub-tree can
+ \li State_Children
+ \li the branch has children (i.e., a new sub-tree can
be opened at the branch).
\row
- \o State_Open
- \o the branch indicator has an opened sub-tree.
+ \li State_Open
+ \li the branch indicator has an opened sub-tree.
\endtable
The tree view (and tree widget) use the style to draw the branches
@@ -1986,14 +1986,14 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o the icon on the toolbox tab
+ \li icon
+ \li the icon on the toolbox tab
\row
- \o text
- \o the text on the toolbox tab
+ \li text
+ \li the text on the toolbox tab
\endtable
\section3 Size Grip
@@ -2014,11 +2014,11 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o corner
- \o a Qt::Corner value that describe which corner in a
+ \li corner
+ \li a Qt::Corner value that describe which corner in a
window (or equivalent) the grip is located.
\endtable
@@ -2038,15 +2038,15 @@
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o opaque
- \o boolean that is true if the rubber band must be
+ \li opaque
+ \li boolean that is true if the rubber band must be
drawn in an opaque style (i.e., color)
\row
- \o shape
- \o a QRubberBand::Shape enum value that holds the
+ \li shape
+ \li a QRubberBand::Shape enum value that holds the
shape of the band (which is either a rectangle or a
line)
\endtable
@@ -2076,24 +2076,24 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o closeable
- \o boolean that holds whether the dock window can be
+ \li closeable
+ \li boolean that holds whether the dock window can be
closed
\row
- \o floatable
- \o boolean that holds whether the dock window can
+ \li floatable
+ \li boolean that holds whether the dock window can
float (i.e., detach from the main window in which
it lives)
\row
- \o movable
- \o boolean that holds whether the window is movable
+ \li movable
+ \li boolean that holds whether the window is movable
(i.e., can move to other dock widget areas)
\row
- \o title
- \o the title text of the dock window
+ \li title
+ \li the title text of the dock window
\endtable
For the buttons, QStyleOptionButton is used (see \l{Tool Buttons}
diff --git a/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc b/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
index a0a8652eaf..eaedb847c8 100644
--- a/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
@@ -51,12 +51,12 @@
Topics:
\list
- \i \l{Overview}
- \i \l{The Style Sheet Syntax}
- \i \l{Qt Designer Integration}
- \i \l{Customizing Qt Widgets Using Style Sheets}
- \i \l{Qt Style Sheets Reference}
- \i \l{Qt Style Sheets Examples}
+ \li \l{Overview}
+ \li \l{The Style Sheet Syntax}
+ \li \l{Qt Designer Integration}
+ \li \l{Customizing Qt Widgets Using Style Sheets}
+ \li \l{Qt Style Sheets Reference}
+ \li \l{Qt Style Sheets Examples}
\endlist
\target overview
@@ -111,17 +111,17 @@
will.
\table
- \row \o \inlineimage stylesheet-coffee-xp.png
- \o \inlineimage stylesheet-pagefold.png
- \row \o Coffee theme running on Windows XP
- \o Pagefold theme running on Windows XP
+ \row \li \inlineimage stylesheet-coffee-xp.png
+ \li \inlineimage stylesheet-pagefold.png
+ \row \li Coffee theme running on Windows XP
+ \li Pagefold theme running on Windows XP
\endtable
\table
- \row \o \inlineimage stylesheet-coffee-cleanlooks.png
- \o \inlineimage stylesheet-pagefold-mac.png
- \row \o Coffee theme running on Ubuntu Linux
- \o Pagefold theme running on Mac OS X
+ \row \li \inlineimage stylesheet-coffee-cleanlooks.png
+ \li \inlineimage stylesheet-pagefold-mac.png
+ \row \li Coffee theme running on Ubuntu Linux
+ \li Pagefold theme running on Mac OS X
\endtable
When a style sheet is active, the QStyle returned by QWidget::style()
@@ -199,24 +199,24 @@
\table 100%
\header
- \o Selector
- \o Example
- \o Explanation
+ \li Selector
+ \li Example
+ \li Explanation
\row
- \o Universal Selector
- \o \c *
- \o Matches all widgets.
+ \li Universal Selector
+ \li \c *
+ \li Matches all widgets.
\row
- \o Type Selector
- \o \c QPushButton
- \o Matches instances of QPushButton and of its subclasses.
+ \li Type Selector
+ \li \c QPushButton
+ \li Matches instances of QPushButton and of its subclasses.
\row
- \o Property Selector
- \o \c{QPushButton[flat="false"]}
- \o Matches instances of QPushButton that are not
+ \li Property Selector
+ \li \c{QPushButton[flat="false"]}
+ \li Matches instances of QPushButton that are not
\l{QPushButton::}{flat}. You may use this selector to test
for any Qt \l{Qt's Property System}{property} that supports
QVariant::toString() (see the \l{QVariant::}{toString()}
@@ -237,29 +237,29 @@
unset the style sheet and set it again.
\row
- \o Class Selector
- \o \c .QPushButton
- \o Matches instances of QPushButton, but not of its subclasses.
+ \li Class Selector
+ \li \c .QPushButton
+ \li Matches instances of QPushButton, but not of its subclasses.
This is equivalent to \c{*[class~="QPushButton"]}.
\row
- \o ID \target ID Selector
+ \li ID \target ID Selector
Selector
- \o \c{QPushButton#okButton}
- \o Matches all QPushButton instances whose
+ \li \c{QPushButton#okButton}
+ \li Matches all QPushButton instances whose
\l{QObject::objectName}{object name} is \c okButton.
\row
- \o Descendant Selector
- \o \c{QDialog QPushButton}
- \o Matches all instances of QPushButton that are descendants
+ \li Descendant Selector
+ \li \c{QDialog QPushButton}
+ \li Matches all instances of QPushButton that are descendants
(children, grandchildren, etc.) of a QDialog.
\row
- \o Child Selector
- \o \c{QDialog > QPushButton}
- \o Matches all instances of QPushButton that are direct
+ \li Child Selector
+ \li \c{QDialog > QPushButton}
+ \li Matches all instances of QPushButton that are direct
children of a QDialog.
\endtable
@@ -329,7 +329,7 @@
Sub-Control} for a realistic example.
\note With complex widgets such as QComboBox and QScrollBar, if one
- property or sub-control is customized, \bold{all} the other properties or
+ property or sub-control is customized, \b{all} the other properties or
sub-controls must be customized as well.
\section1 Pseudo-States
@@ -436,10 +436,10 @@
\e{A selector's specificity is calculated as follows:}
\list
- \o \e{count the number of ID attributes in the selector (= a)}
- \o \e{count the number of other attributes and pseudo-classes in the selector (= b)}
- \o \e{count the number of element names in the selector (= c)}
- \o \e{ignore pseudo-elements [i.e., \l{subcontrols}].}
+ \li \e{count the number of ID attributes in the selector (= a)}
+ \li \e{count the number of other attributes and pseudo-classes in the selector (= b)}
+ \li \e{count the number of element names in the selector (= c)}
+ \li \e{ignore pseudo-elements [i.e., \l{subcontrols}].}
\endlist
\e{Concatenating the three numbers a-b-c (in a number system with a
@@ -495,7 +495,7 @@
In classic CSS, when font and color of an item is not explicitly set,
it gets automatically inherited from the parent. When using Qt Style Sheets,
- a widget does \bold{not} automatically inherit its font and color setting
+ a widget does \b{not} automatically inherit its font and color setting
from its parent widget.
For example, consider a QPushButton inside a QGroupBox:
@@ -589,11 +589,11 @@
\image stylesheet-boxmodel.png
\list
- \o The margin falls outside the border.
- \o The border is drawn between the margin and the padding.
- \o The padding falls inside the border, between the border and
+ \li The margin falls outside the border.
+ \li The border is drawn between the margin and the padding.
+ \li The padding falls inside the border, between the border and
the actual contents.
- \o The content is what is left from the original widget or
+ \li The content is what is left from the original widget or
subcontrol once we have removed the margin, the border, and
the padding.
\endlist
@@ -636,10 +636,10 @@
The steps to render a rule are as follows:
\list
- \o Set clip for entire rendering operation (border-radius)
- \o Draw the background (background-image)
- \o Draw the border (border-image, border)
- \o Draw overlay image (image)
+ \li Set clip for entire rendering operation (border-radius)
+ \li Draw the background (background-image)
+ \li Draw the border (border-image, border)
+ \li Draw overlay image (image)
\endlist
\target sub controls
@@ -650,9 +650,9 @@
followed by the down-arrow sub-control. A QComboBox is thus rendered as
follows:
\list
- \o Render the QComboBox { } rule
- \o Render the QComboBox::drop-down { } rule
- \o Render the QComboBox::down-arrow { } rule
+ \li Render the QComboBox { } rule
+ \li Render the QComboBox::drop-down { } rule
+ \li Render the QComboBox::down-arrow { } rule
\endlist
Sub-controls share a parent-child relationship. In the case of QComboBox,
@@ -666,7 +666,7 @@
Once positioned, sub-controls can be styled using the \l{box model}.
\note With complex widgets such as QComboBox and QScrollBar, if one
- property or sub-control is customized, \bold{all} the other properties or
+ property or sub-control is customized, \b{all} the other properties or
sub-controls must be customized as well.
*/
@@ -691,12 +691,12 @@
\table 100%
\header
- \o Widget
- \o How to Style
+ \li Widget
+ \li How to Style
\row
- \o QAbstractScrollArea \target qabstractscrollarea-widget
- \o Supports the \l{box model}.
+ \li QAbstractScrollArea \target qabstractscrollarea-widget
+ \li Supports the \l{box model}.
All derivatives of QAbstractScrollArea, including QTextEdit,
and QAbstractItemView (all item view classes), support
@@ -711,8 +711,8 @@
{Customizing QAbstractScrollArea} for an example.
\row
- \o QCheckBox \target qcheckbox-widget
- \o Supports the \l{box model}. The check indicator can be
+ \li QCheckBox \target qcheckbox-widget
+ \li Supports the \l{box model}. The check indicator can be
styled using the \l{#indicator-sub}{::indicator}
subcontrol. By default, the indicator is placed in the Top
Left corner of the Contents rectangle of the widget.
@@ -725,15 +725,15 @@
{Customizing QCheckBox} for an example.
\row
- \o QColumnView \target qcolumnview-widget
- \o The grip can be styled be using the \l{image-prop}{image} property.
+ \li QColumnView \target qcolumnview-widget
+ \li The grip can be styled be using the \l{image-prop}{image} property.
The arrow indicators can by styled using the
\l{left-arrow-sub}{::left-arrow} subcontrol and the
\l{right-arrow-sub}{::right-arrow} subcontrol.
\row
- \o QComboBox \target qcombobox-widget
- \o The frame around the combobox can be styled using the
+ \li QComboBox \target qcombobox-widget
+ \li The frame around the combobox can be styled using the
\l{box model}. The drop-down button can be styled using
the \l{#drop-down-sub}{::drop-down} subcontrol. By default, the
drop-down button is placed in the top right corner of the padding
@@ -746,16 +746,16 @@
for an example.
\row
- \o QDateEdit \target qdateedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDateEdit \target qdateedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QDateTimeEdit \target qdatetimeedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDateTimeEdit \target qdatetimeedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QDialog \target qdialog-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
+ \li QDialog \target qdialog-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
\l{#background-clip-prop}{background-clip} and
\l{#background-origin-prop}{background-origin} properties.
@@ -763,13 +763,13 @@
widget.
\row
- \o QDialogButtonBox \target qdialogbuttonbox-widget
- \o The layout of buttons can be altered using the
+ \li QDialogButtonBox \target qdialogbuttonbox-widget
+ \li The layout of buttons can be altered using the
\l{#button-layout-prop}{button-layout} property.
\row
- \o QDockWidget \target qdockwidget-widget
- \o Supports styling of the title bar and the title bar buttons when docked.
+ \li QDockWidget \target qdockwidget-widget
+ \li Supports styling of the title bar and the title bar buttons when docked.
The dock widget border can be styled using the \l{#border-prop}{border}
property. The \l{#title-sub}{::title} subcontrol can be used to customize
@@ -792,12 +792,12 @@
{Customizing QDockWidget} for an example.
\row
- \o QDoubleSpinBox \target qdoublespinbox-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDoubleSpinBox \target qdoublespinbox-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QFrame \target qframe-widget
- \o Supports the \l{box model}.
+ \li QFrame \target qframe-widget
+ \li Supports the \l{box model}.
Since 4.3, setting a stylesheet on a QLabel automatically
sets the QFrame::frameStyle property to QFrame::StyledPanel.
@@ -806,8 +806,8 @@
for an example.
\row
- \o QGroupBox \target qgroupbox-widget
- \o Supports the \l{box model}. The title can be styled using the
+ \li QGroupBox \target qgroupbox-widget
+ \li Supports the \l{box model}. The title can be styled using the
\l{#title-sub}{::title} subcontrol. By default, the title is placed
depending on QGroupBox::textAlignment.
@@ -821,8 +821,8 @@
for an example.
\row
- \o QHeaderView \target qheaderview-widget
- \o Supports the \l{box model}. The sections of the header view are
+ \li QHeaderView \target qheaderview-widget
+ \li Supports the \l{box model}. The sections of the header view are
styled using the \l{#section-sub}{::section} sub control. The
\c{section} Sub-control supports the \l{#middle-ps}{:middle},
\l{#first-ps}{:first}, \l{#last-ps}{:last},
@@ -839,8 +839,8 @@
for an example.
\row
- \o QLabel \target qlabel-widget
- \o Supports the \l{box model}. Does not support the
+ \li QLabel \target qlabel-widget
+ \li Supports the \l{box model}. Does not support the
\l{#hover-ps}{:hover} pseudo-state.
Since 4.3, setting a stylesheet on a QLabel automatically
@@ -850,8 +850,8 @@
example (a QLabel derives from QFrame).
\row
- \o QLineEdit \target qlineedit-widget
- \o Support the \l{box model}.
+ \li QLineEdit \target qlineedit-widget
+ \li Support the \l{box model}.
The color and background of the selected item is styled using
\l{#selection-color-prop}{selection-color} and
@@ -866,8 +866,8 @@
for an example.
\row
- \o QListView \target qlistview-widget
- \o Supports the \l{box model}. When
+ \li QListView \target qlistview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -891,12 +891,12 @@
{Customzing QListView} for an example.
\row
- \o QListWidget \target qlistwidget-widget
- \o See \l{#qlistview-widget}{QListView}.
+ \li QListWidget \target qlistwidget-widget
+ \li See \l{#qlistview-widget}{QListView}.
\row
- \o QMainWindow \target qmainwindow-widget
- \o Supports styling of the separator
+ \li QMainWindow \target qmainwindow-widget
+ \li Supports styling of the separator
The separator in a QMainWindow when using QDockWidget is styled
using the \l{#separator-sub}{::separator} subcontrol.
@@ -905,8 +905,8 @@
for an example.
\row
- \o QMenu \target qmenu-widget
- \o Supports the \l{box model}.
+ \li QMenu \target qmenu-widget
+ \li Supports the \l{box model}.
Individual items are styled using the \l{#item-sub}{::item}
subcontrol. In addition to the usually supported pseudo states,
@@ -933,8 +933,8 @@
for an example.
\row
- \o QMenuBar \target qmenubar-widget
- \o Supports the \l{box model}. The \l{#spacing-prop}{spacing}
+ \li QMenuBar \target qmenubar-widget
+ \li Supports the \l{box model}. The \l{#spacing-prop}{spacing}
property specifies the spacing between menu items.
Individual items are styled using the \l{#item-sub}{::item}
subcontrol.
@@ -946,14 +946,14 @@
for an example.
\row
- \o QMessageBox \target qmessagebox-widget
- \o The \l{#messagebox-text-interaction-flags-prop}
+ \li QMessageBox \target qmessagebox-widget
+ \li The \l{#messagebox-text-interaction-flags-prop}
{messagebox-text-interaction-flags} property can be used to alter
the interaction with text in the message box.
\row
- \o QProgressBar \target qprogressbar-widget
- \o Supports the \l{box model}. The chunks of the progress bar
+ \li QProgressBar \target qprogressbar-widget
+ \li Supports the \l{box model}. The chunks of the progress bar
can be styled using the \l{#chunk-sub}{::chunk} subcontrol.
The chunk is displayed on the Contents rectangle of the widget.
@@ -967,8 +967,8 @@
for an example.
\row
- \o QPushButton \target qpushbutton-widget
- \o Supports the \l{box model}. Supports the \l{#default-ps}{:default},
+ \li QPushButton \target qpushbutton-widget
+ \li Supports the \l{box model}. Supports the \l{#default-ps}{:default},
\l{#flat-ps}{:flat}, \l{#checked-ps}{:checked} pseudo states.
For QPushButton with a menu, the menu indicator is styled
@@ -988,8 +988,8 @@
for an example.
\row
- \o QRadioButton \target qradiobutton-widget
- \o Supports the \l{box model}. The check indicator can be
+ \li QRadioButton \target qradiobutton-widget
+ \li Supports the \l{box model}. The check indicator can be
styled using the \l{#indicator-sub}{::indicator}
subcontrol. By default, the indicator is placed in the Top
Left corner of the Contents rectangle of the widget.
@@ -1002,8 +1002,8 @@
{Customizing QRadioButton} for an example.
\row
- \o QScrollBar \target qscrollbar-widget
- \o Supports the \l{box model}. The Contents rectangle of the widget
+ \li QScrollBar \target qscrollbar-widget
+ \li Supports the \l{box model}. The Contents rectangle of the widget
is considered to be the groove over which the slider moves. The extent
of the QScrollBar (i.e the width or the height depending on the orientation)
is set using the \l{#width-prop}{width} or \l{#height-prop}{height} property
@@ -1037,8 +1037,8 @@
for an example.
\row
- \o QSizeGrip \target qsizegrip-widget
- \o Supports the \l{#width-prop}{width},
+ \li QSizeGrip \target qsizegrip-widget
+ \li Supports the \l{#width-prop}{width},
\l{#height-prop}{height}, and \l{#image-prop}{image}
properties.
@@ -1046,8 +1046,8 @@
for an example.
\row
- \o QSlider \target qslider-widget
- \o Supports the \l{box model}. For horizontal slides, the
+ \li QSlider \target qslider-widget
+ \li Supports the \l{box model}. For horizontal slides, the
\l{min-width-prop}{min-width} and \l{height-prop}{height}
properties must be provided. For vertical sliders, the
\l{min-height-prop}{min-height} and \l{width-prop}{width}
@@ -1064,8 +1064,8 @@
for an example.
\row
- \o QSpinBox \target qspinbox-widget
- \o The frame of the spin box can be styled using the \l{box
+ \li QSpinBox \target qspinbox-widget
+ \li The frame of the spin box can be styled using the \l{box
model}.
The up button and arrow can be styled using the
@@ -1090,16 +1090,16 @@
for an example.
\row
- \o QSplitter \target qsplitter-widget
- \o Supports the \l{box model}. The handle of the splitter
+ \li QSplitter \target qsplitter-widget
+ \li Supports the \l{box model}. The handle of the splitter
is styled using the \l{#handle-sub}{::handle} subcontrol.
See \l{Qt Style Sheets Examples#Customizing QSplitter}{Customizing QSplitter}
for an example.
\row
- \o QStatusBar \target qstatusbar-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}
+ \li QStatusBar \target qstatusbar-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}
{background} property.
The frame for individual items can be style using the
\l{#item-sub}{::item} subcontrol.
@@ -1108,8 +1108,8 @@
for an example.
\row
- \o QTabBar \target qtabbar-widget
- \o Individual tabs may be styled using the \l{#tab-sub}{::tab} subcontrol.
+ \li QTabBar \target qtabbar-widget
+ \li Individual tabs may be styled using the \l{#tab-sub}{::tab} subcontrol.
Close buttons using the \l{#close-button-sub}{::close-button}
The tabs support the
\l{#only-one-ps}{:only-one}, \l{#first-ps}{:first},
@@ -1143,8 +1143,8 @@
for an example.
\row
- \o QTabWidget \target qtabwidget-widget
- \o The frame of the tab widget is styled using the
+ \li QTabWidget \target qtabwidget-widget
+ \li The frame of the tab widget is styled using the
\l{#pane-sub}{::pane} subcontrol. The left and right
corners are styled using the \l{#left-corner-sub}{::left-corner}
and \l{#right-corner-sub}{::right-corner} respectively.
@@ -1163,8 +1163,8 @@
{Customizing QTabWidget} for an example.
\row
- \o QTableView \target qtableview-widget
- \o Supports the \l{box model}. When
+ \li QTableView \target qtableview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -1194,12 +1194,12 @@
{Customzing QTableView} for an example.
\row
- \o QTableWidget \target qtablewidget-widget
- \o See \l{#qtableview-widget}{QTableView}.
+ \li QTableWidget \target qtablewidget-widget
+ \li See \l{#qtableview-widget}{QTableView}.
\row
- \o QTextEdit \target qtextedit-widget
- \o Supports the \l{box model}.
+ \li QTextEdit \target qtextedit-widget
+ \li Supports the \l{box model}.
The color and background of selected text is styled using
\l{#selection-color-prop}{selection-color} and
@@ -1210,12 +1210,12 @@
style scrollable backgrounds.
\row
- \o QTimeEdit \target qtimeedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QTimeEdit \target qtimeedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QToolBar \target qtoolbar-widget
- \o Supports the \l{box model}.
+ \li QToolBar \target qtoolbar-widget
+ \li Supports the \l{box model}.
The \l{#top-ps}{:top}, \l{#left-ps}{:left}, \l{#right-ps}{:right},
\l{#bottom-ps}{:bottom} pseudo states depending on the area in
@@ -1236,8 +1236,8 @@
for an example.
\row
- \o QToolButton \target qtoolbutton-widget
- \o Supports the \l{box model}.
+ \li QToolButton \target qtoolbutton-widget
+ \li Supports the \l{box model}.
If the QToolButton has a menu, is
\l{#menu-indicator-sub}{::menu-indicator} subcontrol can be used to
@@ -1266,8 +1266,8 @@
for an example.
\row
- \o QToolBox \target qtoolbox-widget
- \o Supports the \l{box model}.
+ \li QToolBox \target qtoolbox-widget
+ \li Supports the \l{box model}.
The individual tabs can by styled using the
\l{#tab-sub}{::tab} subcontrol. The tabs support the
@@ -1278,16 +1278,16 @@
\l{#selected-ps}{:selected} pseudo states.
\row
- \o QToolTip \target qtooltip-widget
- \o Supports the \l{box model}. The \l{#opacity-prop}{opacity}
+ \li QToolTip \target qtooltip-widget
+ \li Supports the \l{box model}. The \l{#opacity-prop}{opacity}
property controls the opacity of the tooltip.
See \l{Qt Style Sheets Examples#Customizing QFrame}{Customizing QFrame}
for an example (a QToolTip is a QFrame).
\row
- \o QTreeView \target qtreeview-widget
- \o Supports the \l{box model}. When
+ \li QTreeView \target qtreeview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -1317,12 +1317,12 @@
for an example to style the branches.
\row
- \o QTreeWidget \target qtreewidget-widget
- \o See \l{#qtreeview-widget}{QTreeView}.
+ \li QTreeWidget \target qtreewidget-widget
+ \li See \l{#qtreeview-widget}{QTreeView}.
\row
- \o QWidget \target qwidget-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
+ \li QWidget \target qwidget-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
\l{#background-clip-prop}{background-clip} and
\l{#background-origin-prop}{background-origin} properties.
@@ -1348,14 +1348,14 @@
\table 100%
\header
- \o Property
- \o Type
- \o Description
+ \li Property
+ \li Type
+ \li Description
\row
- \o \bold{\c alternate-background-color} \target alternate-background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The \l{QAbstractItemView::alternatingRowColors}
+ \li \b{\c alternate-background-color} \target alternate-background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The \l{QAbstractItemView::alternatingRowColors}
{alternate background color} used in QAbstractItemView subclasses.
If this property is not set, the default value is
@@ -1370,9 +1370,9 @@
\l{#selection-background-color-prop}{selection-background-color}.
\row
- \o \bold{\c background} \target background-prop
- \o \l{#Background}{Background}
- \o Shorthand notation for setting the background. Equivalent
+ \li \b{\c background} \target background-prop
+ \li \l{#Background}{Background}
+ \li Shorthand notation for setting the background. Equivalent
to specifying \c background-color, \c background-image, \c
background-repeat, and/or \c background-position.
@@ -1404,18 +1404,18 @@
and \l{#alternate-background-color-prop}{alternate-background-color}.
\row
- \o \c background-color \target background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The background color used for the widget.
+ \li \c background-color \target background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The background color used for the widget.
Examples:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 36
\row
- \o \c background-image \target background-image-prop
- \o \l{#Url}{Url}
- \o The background image used for the widget. Semi-transparent
+ \li \c background-image \target background-image-prop
+ \li \l{#Url}{Url}
+ \li The background image used for the widget. Semi-transparent
parts of the image let the \c background-color shine
through.
@@ -1424,9 +1424,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 37
\row
- \o \c background-repeat \target background-repeat-prop
- \o \l{#Repeat}{Repeat}
- \o Whether and how the background image is repeated to fill
+ \li \c background-repeat \target background-repeat-prop
+ \li \l{#Repeat}{Repeat}
+ \li Whether and how the background image is repeated to fill
the \c background-origin rectangle.
If this property is not specified, the background image
@@ -1437,9 +1437,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 38
\row
- \o \c background-position
- \o \l{#Alignment}{Alignment}
- \o The alignment of the background image within the \c
+ \li \c background-position
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of the background image within the \c
background-origin rectangle.
If this property is not specified, the alignment is \c
@@ -1450,9 +1450,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 39
\row
- \o \bold{\c background-attachment} \target background-attachment-prop
- \o \l{#Attachment}{Attachment}
- \o Determines whether the background-image in a QAbstractScrollArea
+ \li \b{\c background-attachment} \target background-attachment-prop
+ \li \l{#Attachment}{Attachment}
+ \li Determines whether the background-image in a QAbstractScrollArea
is scrolled or fixed with respect to the viewport.
By default, the background-image scrolls with the viewport.
@@ -1463,9 +1463,9 @@
See also \l{Qt Style Sheets Reference#background-prop}{background}
\row
- \o \bold{\c background-clip} \target background-clip-prop
- \o \l{#Origin}{Origin}
- \o The widget's rectangle, in which the \c background is drawn.
+ \li \b{\c background-clip} \target background-clip-prop
+ \li \l{#Origin}{Origin}
+ \li The widget's rectangle, in which the \c background is drawn.
This property specifies the rectangle to which the \c background-color
and \c background-image are clipped.
@@ -1487,9 +1487,9 @@
\l{#background-origin-prop}{background-origin} and \l{The Box Model}.
\row
- \o \bold{\c background-origin} \target background-origin-prop
- \o \l{#Origin}{Origin}
- \o The widget's background rectangle, to use in conjunction
+ \li \b{\c background-origin} \target background-origin-prop
+ \li \l{#Origin}{Origin}
+ \li The widget's background rectangle, to use in conjunction
with \c background-position and \c background-image.
This property is supported by QAbstractItemView
@@ -1509,9 +1509,9 @@
\l{The Box Model}.
\row
- \o \bold{\c border} \target border-prop
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's border. Equivalent
+ \li \b{\c border} \target border-prop
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's border. Equivalent
to specifying \c border-color, \c border-style, and/or
\c border-width.
@@ -1526,38 +1526,38 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 43
\row
- \o \c border-top
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's top border.
+ \li \c border-top
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's top border.
Equivalent to specifying \c border-top-color, \c
border-top-style, and/or \c border-top-width.
\row
- \o \c border-right
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's right border.
+ \li \c border-right
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's right border.
Equivalent to specifying \c border-right-color, \c
border-right-style, and/or \c border-right-width.
\row
- \o \c border-bottom
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's bottom border.
+ \li \c border-bottom
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's bottom border.
Equivalent to specifying \c border-bottom-color, \c
border-bottom-style, and/or \c border-bottom-width.
\row
- \o \c border-left
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's left border.
+ \li \c border-left
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's left border.
Equivalent to specifying \c border-left-color, \c
border-left-style, and/or \c border-left-width.
\row
- \o \bold{\c border-color} \target border-attrs
+ \li \b{\c border-color} \target border-attrs
\target border-color-prop
- \o \l{#Box Colors}{Box Colors}
- \o The color of all the border's edges. Equivalent to
+ \li \l{#Box Colors}{Box Colors}
+ \li The color of all the border's edges. Equivalent to
specifying \c border-top-color, \c border-right-color, \c
border-bottom-color, and \c border-left-color.
@@ -1580,29 +1580,29 @@
\l{#border-image-prop}{border-image}, and \l{The Box Model}.
\row
- \o \c border-top-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's top edge.
+ \li \c border-top-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's top edge.
\row
- \o \c border-right-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's right edge.
+ \li \c border-right-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's right edge.
\row
- \o \c border-bottom-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's bottom edge.
+ \li \c border-bottom-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's bottom edge.
\row
- \o \c border-left-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's left edge.
+ \li \c border-left-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's left edge.
\row
- \o \bold{\c border-image} \target border-image-prop
- \o \l{#Border Image}{Border Image}
- \o The image used to fill the border. The image is cut into
+ \li \b{\c border-image} \target border-image-prop
+ \li \l{#Border Image}{Border Image}
+ \li The image used to fill the border. The image is cut into
nine parts and stretched appropriately if necessary. See
\l{#Border Image}{Border Image} for details.
@@ -1618,9 +1618,9 @@
\l{The Box Model}.
\row
- \o \bold{\c border-radius} \target border-radius-prop
- \o \l{#Radius}{Radius}
- \o The radius of the border's corners. Equivalent to
+ \li \b{\c border-radius} \target border-radius-prop
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's corners. Equivalent to
specifying \c border-top-left-radius, \c
border-top-right-radius, \c border-bottom-right-radius,
and \c border-bottom-left-radius.
@@ -1644,32 +1644,32 @@
\l{The Box Model}.
\row
- \o \c border-top-left-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's top-left corner.
+ \li \c border-top-left-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's top-left corner.
\row
- \o \c border-top-right-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's top-right corner.
+ \li \c border-top-right-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's top-right corner.
\row
- \o \c border-bottom-right-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's bottom-right corner. Setting
+ \li \c border-bottom-right-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's bottom-right corner. Setting
this property to a positive value results in a rounded
corner.
\row
- \o \c border-bottom-left-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's bottom-left corner. Setting this
+ \li \c border-bottom-left-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's bottom-left corner. Setting this
property to a positive value results in a rounded corner.
\row
- \o \bold{\c border-style} \target border-style-prop
- \o \l {Border Style}
- \o The style of all the border's edges.
+ \li \b{\c border-style} \target border-style-prop
+ \li \l {Border Style}
+ \li The style of all the border's edges.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -1688,29 +1688,29 @@
\l{#border-image-prop}{border-image}, and \l{The Box Model}.
\row
- \o \c border-top-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's top edge.
+ \li \c border-top-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's top edge.
\row
- \o \c border-right-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's right edge/
+ \li \c border-right-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's right edge/
\row
- \o \c border-bottom-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's bottom edge.
+ \li \c border-bottom-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's bottom edge.
\row
- \o \c border-left-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's left edge.
+ \li \c border-left-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's left edge.
\row
- \o \bold{\c border-width} \target border-width-prop
- \o \l{#Box Lengths}{Box Lengths}
- \o The width of the border. Equivalent to setting \c
+ \li \b{\c border-width} \target border-width-prop
+ \li \l{#Box Lengths}{Box Lengths}
+ \li The width of the border. Equivalent to setting \c
border-top-width, \c border-right-width, \c
border-bottom-width, and \c border-left-width.
@@ -1731,29 +1731,29 @@
\l{The Box Model}.
\row
- \o \c border-top-width
- \o \l{#Length}{Length}
- \o The width of the border's top edge.
+ \li \c border-top-width
+ \li \l{#Length}{Length}
+ \li The width of the border's top edge.
\row
- \o \c border-right-width
- \o \l{#Length}{Length}
- \o The width of the border's right edge.
+ \li \c border-right-width
+ \li \l{#Length}{Length}
+ \li The width of the border's right edge.
\row
- \o \c border-bottom-width
- \o \l{#Length}{Length}
- \o The width of the border's bottom edge.
+ \li \c border-bottom-width
+ \li \l{#Length}{Length}
+ \li The width of the border's bottom edge.
\row
- \o \c border-left-width
- \o \l{#Length}{Length}
- \o The width of the border's left edge.
+ \li \c border-left-width
+ \li \l{#Length}{Length}
+ \li The width of the border's left edge.
\row
- \o \bold{\c bottom} \target bottom-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c bottom} \target bottom-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset up;
specifying \tt{bottom: \e{y}} is then equivalent to
specifying \tt{\l{Qt Style Sheets Reference#top-prop}{top}: -\e{y}}.
@@ -1772,9 +1772,9 @@
\l{Qt Style Sheets Reference#top-prop}{top}.
\row
- \o \bold{\c button-layout} \target button-layout-prop
- \o \l{#Number}{Number}
- \o The layout of buttons in a QDialogButtonBox or
+ \li \b{\c button-layout} \target button-layout-prop
+ \li \l{#Number}{Number}
+ \li The layout of buttons in a QDialogButtonBox or
a QMessageBox. The possible values are 0
(\l{QDialogButtonBox::}{WinLayout}), 1
(\l{QDialogButtonBox::}{MacLayout}), 2
@@ -1790,9 +1790,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 49
\row
- \o \bold{\c color} \target color-prop
- \o \l{#Brush}{Brush} \BR
- \o The color used to render text.
+ \li \b{\c color} \target color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The color used to render text.
This property is supported by all widgets that respect
the \l QWidget::palette.
@@ -1809,9 +1809,9 @@
\l{#selection-color-prop}{selection-color}.
\row
- \o \bold{\c dialogbuttonbox-buttons-have-icons}
- \o \l{#Boolean}{Boolean}
- \o Whether the buttons in a QDialogButtonBox show icons
+ \li \b{\c dialogbuttonbox-buttons-have-icons}
+ \li \l{#Boolean}{Boolean}
+ \li Whether the buttons in a QDialogButtonBox show icons
If this property is set to 1, the buttons of a QDialogButtonBox
show icons; if it is set to 0, the icons are not shown.
@@ -1827,9 +1827,9 @@
\omit
\row
- \o \bold{\c etch-disabled-text}*
- \o \l{#Boolean}{Boolean}
- \o Whether disabled text is drawn etched.
+ \li \b{\c etch-disabled-text}*
+ \li \l{#Boolean}{Boolean}
+ \li Whether disabled text is drawn etched.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -1841,9 +1841,9 @@
\endomit
\row
- \o \bold{\c font} \target font-prop
- \o \l{#Font}{Font}
- \o Shorthand notation for setting the text's font. Equivalent
+ \li \b{\c font} \target font-prop
+ \li \l{#Font}{Font}
+ \li Shorthand notation for setting the text's font. Equivalent
to specifying \c font-family, \c font-size, \c font-style,
and/or \c font-weight.
@@ -1858,18 +1858,18 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 53
\row
- \o \c font-family
- \o String
- \o The font family.
+ \li \c font-family
+ \li String
+ \li The font family.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 54
\row
- \o \c font-size
- \o \l{#Font Size}{Font Size}
- \o The font size. In this version of Qt, only pt and px metrics are
+ \li \c font-size
+ \li \l{#Font Size}{Font Size}
+ \li The font size. In this version of Qt, only pt and px metrics are
supported.
Example:
@@ -1877,23 +1877,23 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 55
\row
- \o \c font-style
- \o \l {Font Style}
- \o The font style.
+ \li \c font-style
+ \li \l {Font Style}
+ \li The font style.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 56
\row
- \o \c font-weight
- \o \l{#Font Weight}{Font Weight}
- \o The weight of the font.
+ \li \c font-weight
+ \li \l{#Font Weight}{Font Weight}
+ \li The weight of the font.
\row
- \o \bold{\c gridline-color}* \target gridline-color-prop
- \o \l{#Color}{Color} \BR
- \o The color of the grid line in a QTableView.
+ \li \b{\c gridline-color}* \target gridline-color-prop
+ \li \l{#Color}{Color} \BR
+ \li The color of the grid line in a QTableView.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -1904,9 +1904,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 57
\row
- \o \bold{\c height} \target height-prop
- \o \l{#Length}{Length}
- \o The height of a \l{subcontrol} (or in some case, a widget).
+ \li \b{\c height} \target height-prop
+ \li \l{#Length}{Length}
+ \li The height of a \l{subcontrol} (or in some case, a widget).
If this property is not specified, it defaults to a value
that depends on the subcontrol/widget and on the current style.
@@ -1923,27 +1923,27 @@
See also \l{#width-prop}{width}.
\row
- \o \bold{\c icon-size} \target icon-size-prop
- \o \l{#Length}{Length}
- \o The width and height of the icon in a widget.
+ \li \b{\c icon-size} \target icon-size-prop
+ \li \l{#Length}{Length}
+ \li The width and height of the icon in a widget.
The icon size of the following widgets can be set using this
property.
\list
- \i QCheckBox
- \i QListView
- \i QPushButton
- \i QRadioButton
- \i QTabBar
- \i QToolBar
- \i QToolBox
- \i QTreeView
+ \li QCheckBox
+ \li QListView
+ \li QPushButton
+ \li QRadioButton
+ \li QTabBar
+ \li QToolBar
+ \li QToolBox
+ \li QTreeView
\endlist
\row
- \o \bold{\c image}* \target image-prop
- \o \l{#Url}{Url}+
- \o The image that is drawn in the contents rectangle of a
+ \li \b{\c image}* \target image-prop
+ \li \l{#Url}{Url}+
+ \li The image that is drawn in the contents rectangle of a
\l{subcontrol}.
The image property accepts a list of \l{#Url}{Url}s or
@@ -1969,15 +1969,15 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 59
\row
- \o \bold{\c image-position} \target image-position-prop
- \o \l{#Alignment}{alignment}
- \o In Qt 4.3 and later, the alignment of the image image's position can be specified
+ \li \b{\c image-position} \target image-position-prop
+ \li \l{#Alignment}{alignment}
+ \li In Qt 4.3 and later, the alignment of the image image's position can be specified
using relative or absolute position.
\row
- \o \bold{\c left} \target left-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c left} \target left-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset to
the right.
@@ -1996,9 +1996,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c lineedit-password-character*} \target lineedit-password-character-prop
- \o \l{#Number}{Number}
- \o The QLineEdit password character as a Unicode number.
+ \li \b{\c lineedit-password-character*} \target lineedit-password-character-prop
+ \li \l{#Number}{Number}
+ \li The QLineEdit password character as a Unicode number.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -2009,9 +2009,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 61
\row
- \o \bold{\c margin} \target margin-prop
- \o \l {Box Lengths}
- \o The widget's margins. Equivalent to specifying \c
+ \li \b{\c margin} \target margin-prop
+ \li \l {Box Lengths}
+ \li The widget's margins. Equivalent to specifying \c
margin-top, \c margin-right, \c margin-bottom, and \c
margin-left.
@@ -2031,29 +2031,29 @@
\l{#spacing-prop}{spacing}, and \l{The Box Model}.
\row
- \o \c margin-top
- \o \l{#Length}{Length}
- \o The widget's top margin.
+ \li \c margin-top
+ \li \l{#Length}{Length}
+ \li The widget's top margin.
\row
- \o \c margin-right
- \o \l{#Length}{Length}
- \o The widget's right margin.
+ \li \c margin-right
+ \li \l{#Length}{Length}
+ \li The widget's right margin.
\row
- \o \c margin-bottom
- \o \l{#Length}{Length}
- \o The widget's bottom margin.
+ \li \c margin-bottom
+ \li \l{#Length}{Length}
+ \li The widget's bottom margin.
\row
- \o \c margin-left
- \o \l{#Length}{Length}
- \o The widget's left margin.
+ \li \c margin-left
+ \li \l{#Length}{Length}
+ \li The widget's left margin.
\row
- \o \bold{\c max-height} \target max-height-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's maximum height.
+ \li \b{\c max-height} \target max-height-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's maximum height.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2071,9 +2071,9 @@
See also \l{#max-width-prop}{max-width}.
\row
- \o \bold{\c max-width} \target max-width-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's maximum width.
+ \li \b{\c max-width} \target max-width-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's maximum width.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2092,9 +2092,9 @@
\row
- \o \bold{\c messagebox-text-interaction-flags*} \target messagebox-text-interaction-flags-prop
- \o \l{#Number}{Number}
- \o The interaction behavior for text in a message box.
+ \li \b{\c messagebox-text-interaction-flags*} \target messagebox-text-interaction-flags-prop
+ \li \l{#Number}{Number}
+ \li The interaction behavior for text in a message box.
Possible values are based on Qt::TextInteractionFlags.
If this property is not specified, it defaults to the
@@ -2107,9 +2107,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 65
\row
- \o \bold{\c min-height} \target min-height-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's minimum height.
+ \li \b{\c min-height} \target min-height-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's minimum height.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2130,9 +2130,9 @@
See also \l{#min-width-prop}{min-width}.
\row
- \o \bold{\c min-width} \target min-width-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's minimum width.
+ \li \b{\c min-width} \target min-width-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's minimum width.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2153,9 +2153,9 @@
See also \l{#min-height-prop}{min-height}.
\row
- \o \bold{\c opacity*} \target opacity-prop
- \o \l{#Number}{Number}
- \o The opacity for a widget. Possible values are from 0
+ \li \b{\c opacity*} \target opacity-prop
+ \li \l{#Number}{Number}
+ \li The opacity for a widget. Possible values are from 0
(transparent) to 255 (opaque). For the moment, this is
only supported for \l{QToolTip}{tooltips}.
@@ -2168,9 +2168,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 68
\row
- \o \bold{\c padding} \target padding-prop
- \o \l{#Box Lengths}{Box Lengths}
- \o The widget's padding. Equivalent to specifying \c
+ \li \b{\c padding} \target padding-prop
+ \li \l{#Box Lengths}{Box Lengths}
+ \li The widget's padding. Equivalent to specifying \c
padding-top, \c padding-right, \c padding-bottom, and \c
padding-left.
@@ -2190,37 +2190,37 @@
\l{#spacing-prop}{spacing}, and \l{The Box Model}.
\row
- \o \c padding-top
- \o \l{#Length}{Length}
- \o The widget's top padding.
+ \li \c padding-top
+ \li \l{#Length}{Length}
+ \li The widget's top padding.
\row
- \o \c padding-right
- \o \l{#Length}{Length}
- \o The widget's right padding.
+ \li \c padding-right
+ \li \l{#Length}{Length}
+ \li The widget's right padding.
\row
- \o \c padding-bottom
- \o \l{#Length}{Length}
- \o The widget's bottom padding.
+ \li \c padding-bottom
+ \li \l{#Length}{Length}
+ \li The widget's bottom padding.
\row
- \o \c padding-left
- \o \l{#Length}{Length}
- \o The widget's left padding.
+ \li \c padding-left
+ \li \l{#Length}{Length}
+ \li The widget's left padding.
\row
- \o \bold{\c paint-alternating-row-colors-for-empty-area}
+ \li \b{\c paint-alternating-row-colors-for-empty-area}
\target paint-alternating-row-colors-for-empty-area-prop
- \o \c bool
- \o Whether the QTreeView paints alternating row colors for the empty
+ \li \c bool
+ \li Whether the QTreeView paints alternating row colors for the empty
area (i.e the area where there are no items)
\row
- \o \bold{\c position} \target position-prop
- \o \c relative \BR
+ \li \b{\c position} \target position-prop
+ \li \c relative \BR
| \c absolute
- \o Whether offsets specified using \l{Qt Style Sheets Reference#left-prop}{left},
+ \li Whether offsets specified using \l{Qt Style Sheets Reference#left-prop}{left},
\l{#right-prop}{right}, \l{Qt Style Sheets Reference#top-prop}{top}, and
\l{#bottom-prop}{bottom} are relative or absolute
coordinates.
@@ -2229,9 +2229,9 @@
relative.
\row
- \o \bold{\c right} \target right-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c right} \target right-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset to
the left; specifying \tt{right: \e{x}} is then equivalent
to specifying \tt{\l{Qt Style Sheets Reference#left-prop}{left}: -\e{x}}.
@@ -2249,9 +2249,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c selection-background-color*} \target selection-background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The background of selected text or items.
+ \li \b{\c selection-background-color*} \target selection-background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The background of selected text or items.
This property is supported by all widgets that respect
the \l QWidget::palette and that show selection text.
@@ -2268,9 +2268,9 @@
\l{Qt Style Sheets Reference#background-prop}{background}.
\row
- \o \bold{\c selection-color*} \target selection-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The foreground of selected text or items.
+ \li \b{\c selection-color*} \target selection-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The foreground of selected text or items.
This property is supported by all widgets that respect
the \l QWidget::palette and that show selection text.
@@ -2288,9 +2288,9 @@
and \l{#color-prop}{color}.
\row
- \o \bold{\c show-decoration-selected*} \target show-decoration-selected-prop
- \o \l{#Boolean}{Boolean}
- \o Controls whether selections in a QListView cover the
+ \li \b{\c show-decoration-selected*} \target show-decoration-selected-prop
+ \li \l{#Boolean}{Boolean}
+ \li Controls whether selections in a QListView cover the
entire row or just the extent of the text.
If this property is not specified, it defaults to the
@@ -2303,9 +2303,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 73
\row
- \o \bold{\c spacing*} \target spacing-prop
- \o \l{#Length}{Length}
- \o Internal spacing in the widget.
+ \li \b{\c spacing*} \target spacing-prop
+ \li \l{#Length}{Length}
+ \li Internal spacing in the widget.
This property is supported by QCheckBox, checkable
\l{QGroupBox}es, QMenuBar, and QRadioButton.
@@ -2321,9 +2321,9 @@
\l{#margin-prop}{margin}.
\row
- \o \bold{\c subcontrol-origin*} \target subcontrol-origin-prop
- \o \l{#Origin}{Origin}
- \o The origin rectangle of the \l subcontrol within the
+ \li \b{\c subcontrol-origin*} \target subcontrol-origin-prop
+ \li \l{#Origin}{Origin}
+ \li The origin rectangle of the \l subcontrol within the
parent element.
If this property is not specified, the default is \c
@@ -2337,9 +2337,9 @@
\l{Qt Style Sheets Reference#subcontrol-position-prop}{subcontrol-position}.
\row
- \o \bold{\c subcontrol-position*} \target subcontrol-position-prop
- \o \l{#Alignment}{Alignment}
- \o The alignment of the \l subcontrol within the origin
+ \li \b{\c subcontrol-position*} \target subcontrol-position-prop
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of the \l subcontrol within the origin
rectangle specified by \l{Qt Style Sheets Reference#subcontrol-origin-prop}
{subcontrol-origin}.
@@ -2354,9 +2354,9 @@
\l{Qt Style Sheets Reference#subcontrol-origin-prop}{subcontrol-origin}.
\row
- \o \bold{\c text-align} \target text-align-prop
- \o \l{#Alignment}{Alignment}
- \o The alignment of text and icon within the contents of the widget.
+ \li \b{\c text-align} \target text-align-prop
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of text and icon within the contents of the widget.
If this value is not specified, it defaults to the value
that depends on the native style.
@@ -2369,17 +2369,17 @@
and QProgressBar.
\row
- \o \bold{\c text-decoration}
- \o \c none \BR
+ \li \b{\c text-decoration}
+ \li \c none \BR
\c underline \BR
\c overline \BR
\c line-through
- \o Additional text effects
+ \li Additional text effects
\row
- \o \bold{\c top} \target top-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c top} \target top-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset
down.
@@ -2398,9 +2398,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c width} \target width-prop
- \o \l{#Length}{Length}
- \o The width of a \l{subcontrol} (or a widget in some cases).
+ \li \b{\c width} \target width-prop
+ \li \l{#Length}{Length}
+ \li The width of a \l{subcontrol} (or a widget in some cases).
If this property is not specified, it defaults to a value
that depends on the subcontrol/widget and on the current style.
@@ -2430,222 +2430,222 @@
\table 100%
\header
- \o Name
- \o QStyle::StandardPixmap
+ \li Name
+ \li QStyle::StandardPixmap
\row
- \o backward-icon
- \o QStyle::SP_ArrowBack
+ \li backward-icon
+ \li QStyle::SP_ArrowBack
\row
- \o cd-icon
- \o QStyle::SP_DriveCDIcon
+ \li cd-icon
+ \li QStyle::SP_DriveCDIcon
\row
- \o computer-icon
- \o QStyle::SP_ComputerIcon
+ \li computer-icon
+ \li QStyle::SP_ComputerIcon
\row
- \o desktop-icon
- \o QStyle::SP_DesktopIcon
+ \li desktop-icon
+ \li QStyle::SP_DesktopIcon
\row
- \o dialog-apply-icon
- \o QStyle::SP_DialogApplyButton
+ \li dialog-apply-icon
+ \li QStyle::SP_DialogApplyButton
\row
- \o dialog-cancel-icon
- \o QStyle::SP_DialogCancelButton
+ \li dialog-cancel-icon
+ \li QStyle::SP_DialogCancelButton
\row
- \o dialog-close-icon
- \o QStyle::SP_DialogCloseButton
+ \li dialog-close-icon
+ \li QStyle::SP_DialogCloseButton
\row
- \o dialog-discard-icon
- \o QStyle::SP_DialogDiscardButton
+ \li dialog-discard-icon
+ \li QStyle::SP_DialogDiscardButton
\row
- \o dialog-help-icon
- \o QStyle::SP_DialogHelpButton
+ \li dialog-help-icon
+ \li QStyle::SP_DialogHelpButton
\row
- \o dialog-no-icon
- \o QStyle::SP_DialogNoButton
+ \li dialog-no-icon
+ \li QStyle::SP_DialogNoButton
\row
- \o dialog-ok-icon
- \o QStyle::SP_DialogOkButton
+ \li dialog-ok-icon
+ \li QStyle::SP_DialogOkButton
\row
- \o dialog-open-icon
- \o QStyle::SP_DialogOpenButton
+ \li dialog-open-icon
+ \li QStyle::SP_DialogOpenButton
\row
- \o dialog-reset-icon
- \o QStyle::SP_DialogResetButton
+ \li dialog-reset-icon
+ \li QStyle::SP_DialogResetButton
\row
- \o dialog-save-icon
- \o QStyle::SP_DialogSaveButton
+ \li dialog-save-icon
+ \li QStyle::SP_DialogSaveButton
\row
- \o dialog-yes-icon
- \o QStyle::SP_DialogYesButton
+ \li dialog-yes-icon
+ \li QStyle::SP_DialogYesButton
\row
- \o directory-closed-icon
- \o QStyle::SP_DirClosedIcon
+ \li directory-closed-icon
+ \li QStyle::SP_DirClosedIcon
\row
- \o directory-icon
- \o QStyle::SP_DirIcon
+ \li directory-icon
+ \li QStyle::SP_DirIcon
\row
- \o directory-link-icon
- \o QStyle::SP_DirLinkIcon
+ \li directory-link-icon
+ \li QStyle::SP_DirLinkIcon
\row
- \o directory-open-icon
- \o QStyle::SP_DirOpenIcon
+ \li directory-open-icon
+ \li QStyle::SP_DirOpenIcon
\row
- \o dockwidget-close-icon
- \o QStyle::SP_DockWidgetCloseButton
+ \li dockwidget-close-icon
+ \li QStyle::SP_DockWidgetCloseButton
\row
- \o downarrow-icon
- \o QStyle::SP_ArrowDown
+ \li downarrow-icon
+ \li QStyle::SP_ArrowDown
\row
- \o dvd-icon
- \o QStyle::SP_DriveDVDIcon
+ \li dvd-icon
+ \li QStyle::SP_DriveDVDIcon
\row
- \o file-icon
- \o QStyle::SP_FileIcon
+ \li file-icon
+ \li QStyle::SP_FileIcon
\row
- \o file-link-icon
- \o QStyle::SP_FileLinkIcon
+ \li file-link-icon
+ \li QStyle::SP_FileLinkIcon
\omit
\row
- \o filedialog-backward-icon
- \o QStyle::SP_FileDialogBack
+ \li filedialog-backward-icon
+ \li QStyle::SP_FileDialogBack
\endomit
\row
- \o filedialog-contentsview-icon
- \o QStyle::SP_FileDialogContentsView
+ \li filedialog-contentsview-icon
+ \li QStyle::SP_FileDialogContentsView
\row
- \o filedialog-detailedview-icon
- \o QStyle::SP_FileDialogDetailedView
+ \li filedialog-detailedview-icon
+ \li QStyle::SP_FileDialogDetailedView
\row
- \o filedialog-end-icon
- \o QStyle::SP_FileDialogEnd
+ \li filedialog-end-icon
+ \li QStyle::SP_FileDialogEnd
\row
- \o filedialog-infoview-icon
- \o QStyle::SP_FileDialogInfoView
+ \li filedialog-infoview-icon
+ \li QStyle::SP_FileDialogInfoView
\row
- \o filedialog-listview-icon
- \o QStyle::SP_FileDialogListView
+ \li filedialog-listview-icon
+ \li QStyle::SP_FileDialogListView
\row
- \o filedialog-new-directory-icon
- \o QStyle::SP_FileDialogNewFolder
+ \li filedialog-new-directory-icon
+ \li QStyle::SP_FileDialogNewFolder
\row
- \o filedialog-parent-directory-icon
- \o QStyle::SP_FileDialogToParent
+ \li filedialog-parent-directory-icon
+ \li QStyle::SP_FileDialogToParent
\row
- \o filedialog-start-icon
- \o QStyle::SP_FileDialogStart
+ \li filedialog-start-icon
+ \li QStyle::SP_FileDialogStart
\row
- \o floppy-icon
- \o QStyle::SP_DriveFDIcon
+ \li floppy-icon
+ \li QStyle::SP_DriveFDIcon
\row
- \o forward-icon
- \o QStyle::SP_ArrowForward
+ \li forward-icon
+ \li QStyle::SP_ArrowForward
\row
- \o harddisk-icon
- \o QStyle::SP_DriveHDIcon
+ \li harddisk-icon
+ \li QStyle::SP_DriveHDIcon
\row
- \o home-icon
- \o QStyle::SP_DirHomeIcon
+ \li home-icon
+ \li QStyle::SP_DirHomeIcon
\row
- \o leftarrow-icon
- \o QStyle::SP_ArrowLeft
+ \li leftarrow-icon
+ \li QStyle::SP_ArrowLeft
\row
- \o messagebox-critical-icon
- \o QStyle::SP_MessageBoxCritical
+ \li messagebox-critical-icon
+ \li QStyle::SP_MessageBoxCritical
\row
- \o messagebox-information-icon
- \o QStyle::SP_MessageBoxInformation
+ \li messagebox-information-icon
+ \li QStyle::SP_MessageBoxInformation
\row
- \o messagebox-question-icon
- \o QStyle::SP_MessageBoxQuestion
+ \li messagebox-question-icon
+ \li QStyle::SP_MessageBoxQuestion
\row
- \o messagebox-warning-icon
- \o QStyle::SP_MessageBoxWarning
+ \li messagebox-warning-icon
+ \li QStyle::SP_MessageBoxWarning
\row
- \o network-icon
- \o QStyle::SP_DriveNetIcon
+ \li network-icon
+ \li QStyle::SP_DriveNetIcon
\row
- \o rightarrow-icon
- \o QStyle::SP_ArrowRight
+ \li rightarrow-icon
+ \li QStyle::SP_ArrowRight
\row
- \o titlebar-contexthelp-icon
- \o QStyle::SP_TitleBarContextHelpButton
+ \li titlebar-contexthelp-icon
+ \li QStyle::SP_TitleBarContextHelpButton
\row
- \o titlebar-maximize-icon
- \o QStyle::SP_TitleBarMaxButton
+ \li titlebar-maximize-icon
+ \li QStyle::SP_TitleBarMaxButton
\row
- \o titlebar-menu-icon
- \o QStyle::SP_TitleBarMenuButton
+ \li titlebar-menu-icon
+ \li QStyle::SP_TitleBarMenuButton
\row
- \o titlebar-minimize-icon
- \o QStyle::SP_TitleBarMinButton
+ \li titlebar-minimize-icon
+ \li QStyle::SP_TitleBarMinButton
\row
- \o titlebar-normal-icon
- \o QStyle::SP_TitleBarNormalButton
+ \li titlebar-normal-icon
+ \li QStyle::SP_TitleBarNormalButton
\row
- \o titlebar-shade-icon
- \o QStyle::SP_TitleBarShadeButton
+ \li titlebar-shade-icon
+ \li QStyle::SP_TitleBarShadeButton
\row
- \o titlebar-unshade-icon
- \o QStyle::SP_TitleBarUnshadeButton
+ \li titlebar-unshade-icon
+ \li QStyle::SP_TitleBarUnshadeButton
\row
- \o trash-icon
- \o QStyle::SP_TrashIcon
+ \li trash-icon
+ \li QStyle::SP_TrashIcon
\row
- \o uparrow-icon
- \o QStyle::SP_ArrowUp
+ \li uparrow-icon
+ \li QStyle::SP_ArrowUp
\endtable
@@ -2656,59 +2656,59 @@
\table 100%
\header
- \o Type
- \o Syntax
- \o Description
+ \li Type
+ \li Syntax
+ \li Description
\row
- \o \bold Alignment \target Alignment
- \o \{ \c top \BR
+ \li \b Alignment \target Alignment
+ \li \{ \c top \BR
| \c bottom \BR
| \c left \BR
| \c right \BR
| \c center \}*
- \o Horizontal and/or vertical alignment.
+ \li Horizontal and/or vertical alignment.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 80
\row
- \o \bold Attachment \target Attachment
- \o \{ \c scroll \BR
+ \li \b Attachment \target Attachment
+ \li \{ \c scroll \BR
| \c fixed \}*
- \o Scroll or fixed attachment.
+ \li Scroll or fixed attachment.
\row
- \o \bold Background \target Background
- \o \{ \l{#Brush}{Brush} \BR
+ \li \b Background \target Background
+ \li \{ \l{#Brush}{Brush} \BR
| \l{#Url}{Url} \BR
| \l{#Repeat}{Repeat} \BR
| \l{#Alignment}{Alignment} \}*
- \o A sequence of \l{#Brush}{Brush}, \l{#Url}{Url},
+ \li A sequence of \l{#Brush}{Brush}, \l{#Url}{Url},
\l{#Repeat}{Repeat}, and \l{#Alignment}{Alignment}.
\row
- \o \bold Boolean \target Boolean
- \o 0 | 1
- \o True (\c 1) or false (\c 0).
+ \li \b Boolean \target Boolean
+ \li 0 | 1
+ \li True (\c 1) or false (\c 0).
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 81
\row
- \o \bold Border \target Border
- \o \{ \l{#Border Style}{Border Style} \BR
+ \li \b Border \target Border
+ \li \{ \l{#Border Style}{Border Style} \BR
| \l{#Length}{Length} \BR
| \l{#Brush}{Brush} \}*
- \o Shorthand border property.
+ \li Shorthand border property.
\row
- \o \bold{Border Image} \target Border Image
- \o \c none \BR
+ \li \b{Border Image} \target Border Image
+ \li \c none \BR
| \l{Url} \l{Number}\{4\} \BR (\c stretch | \c repeat){0,2}
- \o A border image is an image that is composed of nine parts
+ \li A border image is an image that is composed of nine parts
(top left, top center, top right, center left, center,
center right, bottom left, bottom center, and bottom
right). When a border of a certain size is required, the
@@ -2721,8 +2721,8 @@
{CSS3 Draft Specification} for details.
\row
- \o \bold{Border Style} \target Border Style
- \o \c dashed \BR
+ \li \b{Border Style} \target Border Style
+ \li \c dashed \BR
| \c dot-dash \BR
| \c dot-dot-dash \BR
| \c dotted \BR
@@ -2733,14 +2733,14 @@
| \c ridge \BR
| \c solid \BR
| \c none
- \o Specifies the pattern used to draw a border.
+ \li Specifies the pattern used to draw a border.
See the \l{http://www.w3.org/TR/css3-background/#border-style}
{CSS3 Draft Specification} for details.
\row
- \o \bold{Box Colors} \target Box Colors
- \o \l{#Brush}{Brush}\{1,4\}
- \o One to four occurrences of \l{#Brush}{Brush}, specifying the top,
+ \li \b{Box Colors} \target Box Colors
+ \li \l{#Brush}{Brush}\{1,4\}
+ \li One to four occurrences of \l{#Brush}{Brush}, specifying the top,
right, bottom, and left edges of a box, respectively. If
the left color is not specified, it is taken to be the
same as the right color. If the bottom color is not
@@ -2753,9 +2753,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 82
\row
- \o \bold{Box Lengths} \target Box Lengths
- \o \l{#Length}{Length}\{1,4\}
- \o One to four occurrences of \l{#Length}{Length}, specifying the
+ \li \b{Box Lengths} \target Box Lengths
+ \li \l{#Length}{Length}\{1,4\}
+ \li One to four occurrences of \l{#Length}{Length}, specifying the
top, right, bottom, and left edges of a box,
respectively. If the left length is not specified, it is
taken to be the same as the right length. If the bottom
@@ -2768,21 +2768,21 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 83
\row
- \o \bold{Brush} \target Brush
- \o \l{#Color}{Color} \BR
+ \li \b{Brush} \target Brush
+ \li \l{#Color}{Color} \BR
| \l{Gradient} \BR
| \l{PaletteRole}
- \o Specifies a Color or a Gradient or an entry in the Palette.
+ \li Specifies a Color or a Gradient or an entry in the Palette.
\row
- \o \bold{Color} \target Color
- \o \tt{rgb(\e{r}, \e{g}, \e{b})} \BR
+ \li \b{Color} \target Color
+ \li \tt{rgb(\e{r}, \e{g}, \e{b})} \BR
| \tt{rgba(\e{r}, \e{g}, \e{b}, \e{a})} \BR
| \tt{hsv(\e{h}, \e{s}, \e{v})} \BR
| \tt{hsva(\e{h}, \e{s}, \e{v}, \e{a})} \BR
| \tt{#\e{rrggbb}} \BR
| \l{QColor::setNamedColor()}{Color Name} \BR
- \o Specifies a color as RGB (red, green, blue) or RGBA
+ \li Specifies a color as RGB (red, green, blue) or RGBA
(red, green, blue, alpha) or HSV (hue, saturation, value) or HSVA
(hue, saturation, value, alpha) or a named color. The \c rgb() or \c rgba()
syntax can be used with integer values between 0 and 255, or with
@@ -2798,45 +2798,45 @@
\l{http://www.w3.org/TR/CSS21/syndata.html#color-units}{here}.
\row
- \o \bold{Font} \target Font
- \o (\l{#Font Style}{Font Style} | \l{#Font Weight}{Font Weight}){0,2} \l{#Font Size}{Font Size} String
- \o Shorthand font property.
+ \li \b{Font} \target Font
+ \li (\l{#Font Style}{Font Style} | \l{#Font Weight}{Font Weight}){0,2} \l{#Font Size}{Font Size} String
+ \li Shorthand font property.
\row
- \o \bold{Font Size} \target Font Size
- \o \l{Length}
- \o The size of a font.
+ \li \b{Font Size} \target Font Size
+ \li \l{Length}
+ \li The size of a font.
\row
- \o \bold{Font Style} \target Font Style
- \o \c normal \BR
+ \li \b{Font Style} \target Font Style
+ \li \c normal \BR
| \c italic \BR
| \c oblique
- \o The style of a font.
+ \li The style of a font.
\row
- \o \bold{Font Weight} \target Font Weight
- \o \c normal \BR
+ \li \b{Font Weight} \target Font Weight
+ \li \c normal \BR
| \c bold \BR
| \c 100 \BR
| \c 200 \BR
... \BR
| \c 900
- \o The weight of a font.
+ \li The weight of a font.
\row
- \o \bold{Gradient} \target Gradient
- \o \c qlineargradient \BR
+ \li \b{Gradient} \target Gradient
+ \li \c qlineargradient \BR
| \c qradialgradient \BR
| \c qconicalgradient
- \o Specifies gradient fills. There are three types of gradient fills:
+ \li Specifies gradient fills. There are three types of gradient fills:
\list
- \o \e{Linear} gradients interpolate colors between start and
+ \li \e{Linear} gradients interpolate colors between start and
end points.
- \o \e{Radial} gradients interpolate colors between a focal
+ \li \e{Radial} gradients interpolate colors between a focal
point and end points on a circle surrounding it.
- \o \e{Conical} gradients interpolate colors around a center
+ \li \e{Conical} gradients interpolate colors around a center
point.
\endlist
@@ -2855,18 +2855,18 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 85
\row
- \o \bold{Icon} \target Icon
- \o (\l{#Url}{Url} (\c disabled | \c active | \c normal | \c selected)?
+ \li \b{Icon} \target Icon
+ \li (\l{#Url}{Url} (\c disabled | \c active | \c normal | \c selected)?
(\c on | \c off)? )*
- \o A list of url, QIcon::Mode and QIcon::State.
+ \li A list of url, QIcon::Mode and QIcon::State.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 86
\row
- \o \bold{Length} \target Length
- \o \l{#Number}{Number} (\c px | \c pt | \c em | \c ex)?
- \o A number followed by a measurement unit. The CSS standard recommends
+ \li \b{Length} \target Length
+ \li \l{#Number}{Number} (\c px | \c pt | \c em | \c ex)?
+ \li A number followed by a measurement unit. The CSS standard recommends
that user agents must
\l{http://www.w3.org/TR/CSS21/syndata.html#illegalvalues}{ignore}
a declaration with an illegal value. In Qt, it is mandatory to
@@ -2875,32 +2875,32 @@
in most contexts. The supported units are:
\list
- \o \c px: pixels
- \o \c pt: the size of one point (i.e., 1/72 of an inch)
- \o \c em: the em width of the font (i.e., the width of 'M')
- \o \c ex: the ex width of the font (i.e., the height of 'x')
+ \li \c px: pixels
+ \li \c pt: the size of one point (i.e., 1/72 of an inch)
+ \li \c em: the em width of the font (i.e., the width of 'M')
+ \li \c ex: the ex width of the font (i.e., the height of 'x')
\endlist
\row
- \o \bold{Number} \target Number
- \o A decimal integer or a real number
- \o Examples: \c 0, \c 18, \c +127, \c -255, \c 12.34, \c -.5,
+ \li \b{Number} \target Number
+ \li A decimal integer or a real number
+ \li Examples: \c 0, \c 18, \c +127, \c -255, \c 12.34, \c -.5,
\c 0009.
\row
- \o \bold{Origin} \target Origin
- \o \c margin \BR
+ \li \b{Origin} \target Origin
+ \li \c margin \BR
| \c border \BR
| \c padding \BR
| \c content
- \o Indicates which of four rectangles to use.
+ \li Indicates which of four rectangles to use.
\list
- \o \c margin: The margin rectangle. The margin falls outside the border.
- \o \c border: The border rectangle. This is where any border is drawn.
- \o \c padding: The padding rectangle. Unlike the margins,
+ \li \c margin: The margin rectangle. The margin falls outside the border.
+ \li \c border: The border rectangle. This is where any border is drawn.
+ \li \c padding: The padding rectangle. Unlike the margins,
padding is located inside the border.
- \o \c content: The content rectangle. This specifies where
+ \li \c content: The content rectangle. This specifies where
the actual contents go, excluding any
padding, border, or margin.
\endlist
@@ -2908,8 +2908,8 @@
See also \l{The Box Model}.
\row
- \o \bold{PaletteRole} \target PaletteRole
- \o \c alternate-base \BR
+ \li \b{PaletteRole} \target PaletteRole
+ \li \c alternate-base \BR
| \c base \BR
| \c bright-text \BR
| \c button \BR
@@ -2926,40 +2926,40 @@
| \c text \BR
| \c window \BR
| \c window-text \BR
- \o These values correspond the \l{QPalette::ColorRole}{Color roles}
+ \li These values correspond the \l{QPalette::ColorRole}{Color roles}
in the widget's QPalette.
For example,
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 87
\row
- \o \bold{Radius} \target Radius
- \o \l{#Length}{Length}\{1, 2\}
- \o One or two occurrences of \l{#Length}{Length}. If only one length is
+ \li \b{Radius} \target Radius
+ \li \l{#Length}{Length}\{1, 2\}
+ \li One or two occurrences of \l{#Length}{Length}. If only one length is
specified, it is used as the radius of the quarter circle
defining the corner. If two lengths are specified, the
first length is the horizontal radius of a quarter
ellipse, whereas the second length is the vertical radius.
\row
- \o \bold{Repeat} \target Repeat
- \o \c repeat-x \BR
+ \li \b{Repeat} \target Repeat
+ \li \c repeat-x \BR
| \c repeat-y \BR
| \c repeat \BR
| \c no-repeat
- \o A value indicating the nature of repetition.
+ \li A value indicating the nature of repetition.
\list
- \o \c repeat-x: Repeat horizontally.
- \o \c repeat-y: Repeat vertically.
- \o \c repeat: Repeat horizontally and vertically.
- \o \c no-repeat: Don't repeat.
+ \li \c repeat-x: Repeat horizontally.
+ \li \c repeat-y: Repeat vertically.
+ \li \c repeat: Repeat horizontally and vertically.
+ \li \c no-repeat: Don't repeat.
\endlist
\row
- \o \bold{Url} \target Url
- \o \tt{url(\e{filename})}
- \o \tt{\e{filename}} is the name of a file on the local disk
+ \li \b{Url} \target Url
+ \li \tt{url(\e{filename})}
+ \li \tt{\e{filename}} is the name of a file on the local disk
or stored using \l{the Qt Resource System}. Setting an
image implicitly sets the width and height of the element.
@@ -2971,218 +2971,218 @@
\table 100%
\header
- \o Pseudo-State
- \o Description
+ \li Pseudo-State
+ \li Description
- \row \o \c :active \target active
- \o This state is set when the widget resides in an active window.
+ \row \li \c :active \target active
+ \li This state is set when the widget resides in an active window.
\row
- \o \c :adjoins-item \target adjoins-item-ps
- \o This state is set when the \l{#branch-sub}{::branch} of a QTreeView
+ \li \c :adjoins-item \target adjoins-item-ps
+ \li This state is set when the \l{#branch-sub}{::branch} of a QTreeView
is adjacent to an item.
\row
- \o \c :alternate \target alternate-ps
- \o This state is set for every alternate row whe painting the row of
+ \li \c :alternate \target alternate-ps
+ \li This state is set for every alternate row whe painting the row of
a QAbstractItemView when QAbstractItemView::alternatingRowColors()
is set to true.
\row
- \o \c :bottom \target bottom-ps
- \o The item is positioned at the bottom. For example, a QTabBar
+ \li \c :bottom \target bottom-ps
+ \li The item is positioned at the bottom. For example, a QTabBar
that has its tabs positioned at the bottom.
\row
- \o \c :checked \target checked-ps
- \o The item is checked. For example, the
+ \li \c :checked \target checked-ps
+ \li The item is checked. For example, the
\l{QAbstractButton::checked}{checked} state of QAbstractButton.
\row
- \o \c :closable \target closable-ps
- \o The items can be closed. For example, the QDockWidget has the
+ \li \c :closable \target closable-ps
+ \li The items can be closed. For example, the QDockWidget has the
QDockWidget::DockWidgetClosable feature turned on.
\row
- \o \c :closed \target closed-ps
- \o The item is in the closed state. For example, an non-expanded
+ \li \c :closed \target closed-ps
+ \li The item is in the closed state. For example, an non-expanded
item in a QTreeView
\row
- \o \c :default \target default-ps
- \o The item is the default. For example, a
+ \li \c :default \target default-ps
+ \li The item is the default. For example, a
\l{QPushButton::default}{default} QPushButton or a default action
in a QMenu.
\row
- \o \c :disabled \target disabled-ps
- \o The item is \l{QWidget::enabled}{disabled}.
+ \li \c :disabled \target disabled-ps
+ \li The item is \l{QWidget::enabled}{disabled}.
\row
- \o \c :editable \target editable-ps
- \o The QComboBox is editable.
+ \li \c :editable \target editable-ps
+ \li The QComboBox is editable.
\row
- \o \c :edit-focus \target edit-focus-ps
- \o The item has edit focus (See QStyle::State_HasEditFocus). This state
+ \li \c :edit-focus \target edit-focus-ps
+ \li The item has edit focus (See QStyle::State_HasEditFocus). This state
is available only for Qt Extended applications.
\row
- \o \c :enabled \target enabled-ps
- \o The item is \l{QWidget::enabled}{enabled}.
+ \li \c :enabled \target enabled-ps
+ \li The item is \l{QWidget::enabled}{enabled}.
\row
- \o \c :exclusive \target exclusive-ps
- \o The item is part of an exclusive item group. For example, a menu
+ \li \c :exclusive \target exclusive-ps
+ \li The item is part of an exclusive item group. For example, a menu
item in a exclusive QActionGroup.
\row
- \o \c :first \target first-ps
- \o The item is the first (in a list). For example, the first
+ \li \c :first \target first-ps
+ \li The item is the first (in a list). For example, the first
tab in a QTabBar.
\row
- \o \c :flat \target flat-ps
- \o The item is flat. For example, a
+ \li \c :flat \target flat-ps
+ \li The item is flat. For example, a
\l{QPushButton::flat}{flat} QPushButton.
\row
- \o \c :floatable \target floatable-ps
- \o The items can be floated. For example, the QDockWidget has the
+ \li \c :floatable \target floatable-ps
+ \li The items can be floated. For example, the QDockWidget has the
QDockWidget::DockWidgetFloatable feature turned on.
\row
- \o \c :focus \target focus-ps
- \o The item has \l{QWidget::hasFocus()}{input focus}.
+ \li \c :focus \target focus-ps
+ \li The item has \l{QWidget::hasFocus()}{input focus}.
\row
- \o \c :has-children \target has-children-ps
- \o The item has children. For example, an item in a
+ \li \c :has-children \target has-children-ps
+ \li The item has children. For example, an item in a
QTreeView that has child items.
\row
- \o \c :has-siblings \target has-siblings-ps
- \o The item has siblings. For example, an item in a
+ \li \c :has-siblings \target has-siblings-ps
+ \li The item has siblings. For example, an item in a
QTreeView that siblings.
\row
- \o \c :horizontal \target horizontal-ps
- \o The item has horizontal orientation
+ \li \c :horizontal \target horizontal-ps
+ \li The item has horizontal orientation
\row
- \o \c :hover \target hover-ps
- \o The mouse is hovering over the item.
+ \li \c :hover \target hover-ps
+ \li The mouse is hovering over the item.
\row
- \o \c :indeterminate \target indeterminate-ps
- \o The item has indeterminate state. For example, a QCheckBox
+ \li \c :indeterminate \target indeterminate-ps
+ \li The item has indeterminate state. For example, a QCheckBox
or QRadioButton is \l{Qt::PartiallyChecked}{partially checked}.
\row
- \o \c :last \target last-ps
- \o The item is the last (in a list). For example, the last
+ \li \c :last \target last-ps
+ \li The item is the last (in a list). For example, the last
tab in a QTabBar.
\row
- \o \c :left \target left-ps
- \o The item is positioned at the left. For example, a QTabBar
+ \li \c :left \target left-ps
+ \li The item is positioned at the left. For example, a QTabBar
that has its tabs positioned at the left.
\row
- \o \c :maximized \target maximized-ps
- \o The item is maximized. For example, a maximized QMdiSubWindow.
+ \li \c :maximized \target maximized-ps
+ \li The item is maximized. For example, a maximized QMdiSubWindow.
\row
- \o \c :middle \target middle-ps
- \o The item is in the middle (in a list). For example, a tab
+ \li \c :middle \target middle-ps
+ \li The item is in the middle (in a list). For example, a tab
that is not in the beginning or the end in a QTabBar.
\row
- \o \c :minimized \target minimized-ps
- \o The item is minimized. For example, a minimized QMdiSubWindow.
+ \li \c :minimized \target minimized-ps
+ \li The item is minimized. For example, a minimized QMdiSubWindow.
\row
- \o \c :movable \target movable-ps
- \o The item can be moved around. For example, the QDockWidget has the
+ \li \c :movable \target movable-ps
+ \li The item can be moved around. For example, the QDockWidget has the
QDockWidget::DockWidgetMovable feature turned on.
\row
- \o \c :no-frame \target no-frame-ps
- \o The item has no frame. For example, a frameless QSpinBox
+ \li \c :no-frame \target no-frame-ps
+ \li The item has no frame. For example, a frameless QSpinBox
or QLineEdit.
\row
- \o \c :non-exclusive \target non-exclusive-ps
- \o The item is part of a non-exclusive item group. For example, a menu
+ \li \c :non-exclusive \target non-exclusive-ps
+ \li The item is part of a non-exclusive item group. For example, a menu
item in a non-exclusive QActionGroup.
\row
- \o \c :off \target off-ps
- \o For items that can be toggled, this applies to items
+ \li \c :off \target off-ps
+ \li For items that can be toggled, this applies to items
in the "off" state.
\row
- \o \c :on \target on-ps
- \o For items that can be toggled, this applies to widgets
+ \li \c :on \target on-ps
+ \li For items that can be toggled, this applies to widgets
in the "on" state.
\row
- \o \c :only-one \target only-one-ps
- \o The item is the only one (in a list). For example, a lone tab
+ \li \c :only-one \target only-one-ps
+ \li The item is the only one (in a list). For example, a lone tab
in a QTabBar.
\row
- \o \c :open \target open-ps
- \o The item is in the open state. For example, an expanded
+ \li \c :open \target open-ps
+ \li The item is in the open state. For example, an expanded
item in a QTreeView, or a QComboBox or QPushButton with
an open menu.
\row
- \o \c :next-selected \target next-selected-ps
- \o The next item (in a list) is selected. For example, the
+ \li \c :next-selected \target next-selected-ps
+ \li The next item (in a list) is selected. For example, the
selected tab of a QTabBar is next to this item.
\row
- \o \c :pressed \target pressed-ps
- \o The item is being pressed using the mouse.
+ \li \c :pressed \target pressed-ps
+ \li The item is being pressed using the mouse.
\row
- \o \c :previous-selected \target previous-selected-ps
- \o The previous item (in a list) is selected. For example, a
+ \li \c :previous-selected \target previous-selected-ps
+ \li The previous item (in a list) is selected. For example, a
tab in a QTabBar that is next to the selected tab.
\row
- \o \c :read-only \target read-only-ps
- \o The item is marked read only or non-editable. For example,
+ \li \c :read-only \target read-only-ps
+ \li The item is marked read only or non-editable. For example,
a read only QLineEdit or a non-editable QComboBox.
\row
- \o \c :right \target right-ps
- \o The item is positioned at the right. For example, a QTabBar
+ \li \c :right \target right-ps
+ \li The item is positioned at the right. For example, a QTabBar
that has its tabs positioned at the right.
\row
- \o \c :selected \target selected-ps
- \o The item is selected. For example, the selected tab in
+ \li \c :selected \target selected-ps
+ \li The item is selected. For example, the selected tab in
a QTabBar or the selected item in a QMenu.
\row
- \o \c :top \target top-ps
- \o The item is positioned at the top. For example, a QTabBar
+ \li \c :top \target top-ps
+ \li The item is positioned at the top. For example, a QTabBar
that has its tabs positioned at the top.
\row
- \o \c :unchecked \target unchecked-ps
- \o The item is
+ \li \c :unchecked \target unchecked-ps
+ \li The item is
\l{QAbstractButton::checked}{unchecked}.
\row
- \o \c :vertical \target vertical-ps
- \o The item has vertical orientation.
+ \li \c :vertical \target vertical-ps
+ \li The item has vertical orientation.
\row
- \o \c :window \target window-ps
- \o The widget is a window (i.e top level widget)
+ \li \c :window \target window-ps
+ \li The widget is a window (i.e top level widget)
\endtable
@@ -3193,162 +3193,162 @@
\table 100%
\header
- \o Sub-Control
- \o Description
+ \li Sub-Control
+ \li Description
\row
- \o \c ::add-line \target add-line-sub
- \o The button to add a line of a QScrollBar.
+ \li \c ::add-line \target add-line-sub
+ \li The button to add a line of a QScrollBar.
\row
- \o \c ::add-page \target add-page-sub
- \o The region between the handle (slider) and the \l{#add-line-sub}{add-line}
+ \li \c ::add-page \target add-page-sub
+ \li The region between the handle (slider) and the \l{#add-line-sub}{add-line}
of a QScrollBar.
\row
- \o \c ::branch \target branch-sub
- \o The branch indicator of a QTreeView.
+ \li \c ::branch \target branch-sub
+ \li The branch indicator of a QTreeView.
\row
- \o \c ::chunk \target chunk-sub
- \o The progress chunk of a QProgressBar.
+ \li \c ::chunk \target chunk-sub
+ \li The progress chunk of a QProgressBar.
\row
- \o \c ::close-button \target close-button-sub
- \o The close button of a QDockWidget or tabs of QTabBar
+ \li \c ::close-button \target close-button-sub
+ \li The close button of a QDockWidget or tabs of QTabBar
\row
- \o \c ::corner \target corner-sub
- \o The corner between two scrollbars in a QAbstractScrollArea
+ \li \c ::corner \target corner-sub
+ \li The corner between two scrollbars in a QAbstractScrollArea
\row
- \o \c ::down-arrow \target down-arrow-sub
- \o The down arrow of a QComboBox, QHeaderView (sort indicator),
+ \li \c ::down-arrow \target down-arrow-sub
+ \li The down arrow of a QComboBox, QHeaderView (sort indicator),
QScrollBar or QSpinBox.
\row
- \o \c ::down-button \target down-button-sub
- \o The down button of a QScrollBar or a QSpinBox.
+ \li \c ::down-button \target down-button-sub
+ \li The down button of a QScrollBar or a QSpinBox.
\row
- \o \c ::drop-down \target drop-down-sub
- \o The drop-down button of a QComboBox.
+ \li \c ::drop-down \target drop-down-sub
+ \li The drop-down button of a QComboBox.
\row
- \o \c ::float-button \target float-button-sub
- \o The float button of a QDockWidget
+ \li \c ::float-button \target float-button-sub
+ \li The float button of a QDockWidget
\row
- \o \c ::groove \target groove-sub
- \o The groove of a QSlider.
+ \li \c ::groove \target groove-sub
+ \li The groove of a QSlider.
\row
- \o \c ::indicator \target indicator-sub
- \o The indicator of a QAbstractItemView, a QCheckBox, a QRadioButton,
+ \li \c ::indicator \target indicator-sub
+ \li The indicator of a QAbstractItemView, a QCheckBox, a QRadioButton,
a checkable QMenu item or a checkable QGroupBox.
\row
- \o \c ::handle \target handle-sub
- \o The handle (slider) of a QScrollBar, a QSplitter, or a QSlider.
+ \li \c ::handle \target handle-sub
+ \li The handle (slider) of a QScrollBar, a QSplitter, or a QSlider.
\row
- \o \c ::icon \target icon-sub
- \o The icon of a QAbstractItemView or a QMenu.
+ \li \c ::icon \target icon-sub
+ \li The icon of a QAbstractItemView or a QMenu.
\row
- \o \c ::item \target item-sub
- \o An item of a QAbstractItemView, a QMenuBar, a QMenu, or
+ \li \c ::item \target item-sub
+ \li An item of a QAbstractItemView, a QMenuBar, a QMenu, or
a QStatusBar.
\row
- \o \c ::left-arrow \target left-arrow-sub
- \o The left arrow of a QScrollBar.
+ \li \c ::left-arrow \target left-arrow-sub
+ \li The left arrow of a QScrollBar.
\row
- \o \c ::left-corner \target left-corner-sub
- \o The left corner of a QTabWidget. For example, this control can be
+ \li \c ::left-corner \target left-corner-sub
+ \li The left corner of a QTabWidget. For example, this control can be
used to control position the left corner widget in a QTabWidget.
\row
- \o \c ::menu-arrow \target menu-arrow-sub
- \o The arrow of a QToolButton with a menu.
+ \li \c ::menu-arrow \target menu-arrow-sub
+ \li The arrow of a QToolButton with a menu.
\row
- \o \c ::menu-button \target menu-button-sub
- \o The menu button of a QToolButton.
+ \li \c ::menu-button \target menu-button-sub
+ \li The menu button of a QToolButton.
\row
- \o \c ::menu-indicator \target menu-indicator-sub
- \o The menu indicator of a QPushButton.
+ \li \c ::menu-indicator \target menu-indicator-sub
+ \li The menu indicator of a QPushButton.
\row
- \o \c ::right-arrow \target right-arrow-sub
- \o The right arrow of a QMenu or a QScrollBar.
+ \li \c ::right-arrow \target right-arrow-sub
+ \li The right arrow of a QMenu or a QScrollBar.
\row
- \o \c ::pane \target pane-sub
- \o The pane (frame) of a QTabWidget.
+ \li \c ::pane \target pane-sub
+ \li The pane (frame) of a QTabWidget.
\row
- \o \c ::right-corner \target right-corner-sub
- \o The right corner of a QTabWidget. For example, this control can be
+ \li \c ::right-corner \target right-corner-sub
+ \li The right corner of a QTabWidget. For example, this control can be
used to control the position the right corner widget in a QTabWidget.
\row
- \o \c ::scroller \target scroller-sub
- \o The scroller of a QMenu or QTabBar.
+ \li \c ::scroller \target scroller-sub
+ \li The scroller of a QMenu or QTabBar.
\row
- \o \c ::section \target section-sub
- \o The section of a QHeaderView.
+ \li \c ::section \target section-sub
+ \li The section of a QHeaderView.
\row
- \o \c ::separator \target separator-sub
- \o The separator of a QMenu or in a QMainWindow.
+ \li \c ::separator \target separator-sub
+ \li The separator of a QMenu or in a QMainWindow.
\row
- \o \c ::sub-line \target sub-line-sub
- \o The button to subtract a line of a QScrollBar.
+ \li \c ::sub-line \target sub-line-sub
+ \li The button to subtract a line of a QScrollBar.
\row
- \o \c ::sub-page \target sub-page-sub
- \o The region between the handle (slider) and the \l{#sub-line-sub}{sub-line}
+ \li \c ::sub-page \target sub-page-sub
+ \li The region between the handle (slider) and the \l{#sub-line-sub}{sub-line}
of a QScrollBar.
\row
- \o \c ::tab \target tab-sub
- \o The tab of a QTabBar or QToolBox.
+ \li \c ::tab \target tab-sub
+ \li The tab of a QTabBar or QToolBox.
\row
- \o \c ::tab-bar \target tab-bar-sub
- \o The tab bar of a QTabWidget. This subcontrol exists only to
+ \li \c ::tab-bar \target tab-bar-sub
+ \li The tab bar of a QTabWidget. This subcontrol exists only to
control the position of the QTabBar inside the QTabWidget. To
style the tabs using the \l{#tab-sub}{::tab} subcontrol.
\row
- \o \c ::tear \target tear-sub
- \o The tear indicator of a QTabBar.
+ \li \c ::tear \target tear-sub
+ \li The tear indicator of a QTabBar.
\row
- \o \c ::tearoff \target tearoff-sub
- \o The tear-off indicator of a QMenu.
+ \li \c ::tearoff \target tearoff-sub
+ \li The tear-off indicator of a QMenu.
\row
- \o \c ::text \target text-ps
- \o The text of a QAbstractItemView.
+ \li \c ::text \target text-ps
+ \li The text of a QAbstractItemView.
\row
- \o \c ::title \target title-sub
- \o The title of a QGroupBox or a QDockWidget.
+ \li \c ::title \target title-sub
+ \li The title of a QGroupBox or a QDockWidget.
\row
- \o \c ::up-arrow \target up-arrow-sub
- \o The up arrow of a QHeaderView (sort indicator), QScrollBar
+ \li \c ::up-arrow \target up-arrow-sub
+ \li The up arrow of a QHeaderView (sort indicator), QScrollBar
or a QSpinBox.
\row
- \o \c ::up-button \target up-button-sub
- \o The up button of a QSpinBox.
+ \li \c ::up-button \target up-button-sub
+ \li The up button of a QSpinBox.
\endtable
@@ -3441,11 +3441,11 @@
What happened is this:
\list
- \o We have made a request that cannot be satisfied using the
+ \li We have made a request that cannot be satisfied using the
native styles alone (e.g., the Windows XP theme engine doesn't
let us specify the background color of a button).
- \o Therefore, the button is rendered using style sheets.
- \o We haven't specified any values for
+ \li Therefore, the button is rendered using style sheets.
+ \li We haven't specified any values for
\l{Qt Style Sheets Reference#border-width-prop}{border-width} and
\l{Qt Style Sheets Reference#border-style-prop}{border-style}, so by default we obtain
a 0-pixel wide border of style \c none.
@@ -3836,18 +3836,18 @@
There are three types of QToolButtons.
\list
- \i The QToolButton has no menu. In this case, the QToolButton is styled
+ \li The QToolButton has no menu. In this case, the QToolButton is styled
exactly like QPushButton. See
\l{#Customizing QPushButton}{Customizing QPushButton} for an
example.
- \i The QToolButton has a menu and has the QToolButton::popupMode set to
+ \li The QToolButton has a menu and has the QToolButton::popupMode set to
QToolButton::DelayedPopup or QToolButton::InstantPopup. In this case,
the QToolButton is styled exactly like a QPushButton with a menu.
See \l{#Customizing QPushButton}{Customizing QPushButton} for an
example of the usage of the menu-indicator pseudo state.
- \i The QToolButton has its QToolButton::popupMode set to
+ \li The QToolButton has its QToolButton::popupMode set to
QToolButton::MenuButtonPopup. In this case, we style it as follows:
\endlist
@@ -3885,17 +3885,17 @@
\table
\row
- \o \inlineimage stylesheet-vline.png
- \o \inlineimage stylesheet-branch-more.png
- \o \inlineimage stylesheet-branch-end.png
- \o \inlineimage stylesheet-branch-closed.png
- \o \inlineimage stylesheet-branch-open.png
- \row
- \o vline.png
- \o branch-more.png
- \o branch-end.png
- \o branch-closed.png
- \o branch-open.png
+ \li \inlineimage stylesheet-vline.png
+ \li \inlineimage stylesheet-branch-more.png
+ \li \inlineimage stylesheet-branch-end.png
+ \li \inlineimage stylesheet-branch-closed.png
+ \li \inlineimage stylesheet-branch-open.png
+ \row
+ \li vline.png
+ \li branch-more.png
+ \li branch-end.png
+ \li branch-closed.png
+ \li branch-open.png
\endtable
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 158
@@ -3948,16 +3948,16 @@
\table
\row
- \o \inlineimage stylesheet-border-image-stretched.png
+ \li \inlineimage stylesheet-border-image-stretched.png
\row
- \o With borders
+ \li With borders
\endtable
\table
\row
- \o \inlineimage stylesheet-border-image-wrong.png
+ \li \inlineimage stylesheet-border-image-wrong.png
\row
- \o Without borders
+ \li Without borders
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/widgets.qdoc b/doc/src/widgets/widgets-and-layouts/widgets.qdoc
index a84f12e70f..e80b0fbec0 100644
--- a/doc/src/widgets/widgets-and-layouts/widgets.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/widgets.qdoc
@@ -58,8 +58,8 @@
\table
\row
- \o \image qgridlayout-with-5-children.png
- \o \image qformlayout-with-6-children.png
+ \li \image qgridlayout-with-5-children.png
+ \li \image qformlayout-with-6-children.png
\endtable
\l{Qt Designer Manual}{\QD} is a powerful tool for interactively creating and
@@ -74,9 +74,9 @@
\table
\row
- \o \image windowsxp-tabwidget.png
- \o \image plastique-tabwidget.png
- \o \image macintosh-tabwidget.png
+ \li \image windowsxp-tabwidget.png
+ \li \image plastique-tabwidget.png
+ \li \image macintosh-tabwidget.png
\endtable
\l{Qt Style Sheets} are a powerful mechanism that allows you to customize the
@@ -94,13 +94,13 @@
\table
\row
- \o \image windows-label.png
- \o \image windowsvista-pushbutton.png
- \o \image gtk-progressbar.png
+ \li \image windows-label.png
+ \li \image windowsvista-pushbutton.png
+ \li \image gtk-progressbar.png
\row
- \o \image plastique-combobox.png
- \o \image macintosh-radiobutton.png
- \o \image cde-lineedit.png
+ \li \image plastique-combobox.png
+ \li \image macintosh-radiobutton.png
+ \li \image cde-lineedit.png
\endtable
\annotatedlist basicwidgets
@@ -112,17 +112,17 @@
\table
\row
- \o \image windowsxp-treeview.png
- \o \image gtk-calendarwidget.png
- \o \image qundoview.png
+ \li \image windowsxp-treeview.png
+ \li \image gtk-calendarwidget.png
+ \li \image qundoview.png
\endtable
\annotatedlist advanced
\table
\row
- \o \image windowsvista-tabwidget.png
- \o \image macintosh-groupbox.png
+ \li \image windowsvista-tabwidget.png
+ \li \image macintosh-groupbox.png
\endtable
\section2 Organizer Widgets
diff --git a/doc/src/widgets/widgets-tutorial.qdoc b/doc/src/widgets/widgets-tutorial.qdoc
index 1d010651e5..735a7ebc54 100644
--- a/doc/src/widgets/widgets-tutorial.qdoc
+++ b/doc/src/widgets/widgets-tutorial.qdoc
@@ -78,13 +78,13 @@
the \c main() function.
\list
- \o \l {tutorials/widgets/toplevel} {Creating a window}
+ \li \l {tutorials/widgets/toplevel} {Creating a window}
- \o \l {tutorials/widgets/childwidget} {Creating child widgets}
+ \li \l {tutorials/widgets/childwidget} {Creating child widgets}
- \o \l {tutorials/widgets/windowlayout} {Using layouts}
+ \li \l {tutorials/widgets/windowlayout} {Using layouts}
- \o \l {tutorials/widgets/nestedlayouts} {Nested layouts}
+ \li \l {tutorials/widgets/nestedlayouts} {Nested layouts}
\endlist
\section1 Real world widget examples
@@ -103,14 +103,14 @@
\list 1
- \o From a command prompt, enter the directory containing the
+ \li From a command prompt, enter the directory containing the
example you have modified.
- \o Type \c qmake and press \key{Return}. If this doesn't work,
+ \li Type \c qmake and press \key{Return}. If this doesn't work,
make sure that the executable is on your path, or enter its
full location.
- \o On Linux/Unix and Mac OS X, type \c make and press
+ \li On Linux/Unix and Mac OS X, type \c make and press
\key{Return}; on Windows with Visual Studio, type \c nmake and
press \key{Return}.
@@ -137,8 +137,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/toplevel/main.cpp main program
- \o \inlineimage widgets-tutorial-toplevel.png
+ \li \snippet tutorials/widgets/toplevel/main.cpp main program
+ \li \inlineimage widgets-tutorial-toplevel.png
\endtable
\enddiv
@@ -159,8 +159,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/childwidget/main.cpp main program
- \o \inlineimage widgets-tutorial-childwidget.png
+ \li \snippet tutorials/widgets/childwidget/main.cpp main program
+ \li \inlineimage widgets-tutorial-childwidget.png
\endtable
\enddiv
@@ -181,8 +181,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/windowlayout/main.cpp main program
- \o \inlineimage widgets-tutorial-windowlayout.png
+ \li \snippet tutorials/widgets/windowlayout/main.cpp main program
+ \li \inlineimage widgets-tutorial-windowlayout.png
\endtable
\enddiv
@@ -219,9 +219,9 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/nestedlayouts/main.cpp first part
+ \li \snippet tutorials/widgets/nestedlayouts/main.cpp first part
\snippet tutorials/widgets/nestedlayouts/main.cpp last part
- \o \inlineimage widgets-tutorial-nestedlayouts.png
+ \li \inlineimage widgets-tutorial-nestedlayouts.png
\endtable
\enddiv
diff --git a/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc b/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
index 1517116c05..3a2efb06a2 100644
--- a/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
+++ b/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
@@ -94,13 +94,13 @@
most common usage transparently.
\list
- \o \bold{Including the window frame:}
+ \li \b{Including the window frame:}
\l{QWidget::x()}{x()},
\l{QWidget::y()}{y()},
\l{QWidget::frameGeometry()}{frameGeometry()},
\l{QWidget::pos()}{pos()}, and
\l{QWidget::move()}{move()}.
- \o \bold{Excluding the window frame:}
+ \li \b{Excluding the window frame:}
\l{QWidget::geometry()}{geometry()},
\l{QWidget::width()}{width()},
\l{QWidget::height()}{height()},
@@ -169,17 +169,17 @@
associated user interface components:
\list
- \o QMainWindow remains the central class around which applications
+ \li QMainWindow remains the central class around which applications
can be built. The interface to this class has been simplified, and
much of the functionality previously included in this class is now
present in the companion QDockWidget and QToolBar classes.
- \o QDockWidget provides a widget that can be used to create
+ \li QDockWidget provides a widget that can be used to create
detachable tool palettes or helper windows. Dock widgets keep track
of their own properties, and they can be moved, closed, and floated
as external windows.
- \o QToolBar provides a generic toolbar widget that can hold a
+ \li QToolBar provides a generic toolbar widget that can hold a
number of different action-related widgets, such as buttons,
drop-down menus, comboboxes, and spin boxes. The emphasis on a
unified action model in Qt 4 means that toolbars cooperate well
diff --git a/examples/opengl/cube/cube.pro b/examples/opengl/cube/cube.pro
index ef6f526067..98a3082340 100644
--- a/examples/opengl/cube/cube.pro
+++ b/examples/opengl/cube/cube.pro
@@ -1,9 +1,3 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2010-06-23T12:55:35
-#
-#-------------------------------------------------
-
QT += core gui widgets
TARGET = cube
@@ -12,7 +6,6 @@ TEMPLATE = app
SOURCES += main.cpp
contains(QT_CONFIG, opengl) {
- message(Building with OpenGL support.)
QT += opengl
SOURCES += mainwidget.cpp \
@@ -29,8 +22,6 @@ contains(QT_CONFIG, opengl) {
OTHER_FILES += \
vshader.glsl \
fshader.glsl
-} else {
- message(OpenGL support is not available.)
}
diff --git a/examples/webkit/webkit-guide/_index.html b/examples/webkit/webkit-guide/_index.html
index 5d7dd11d63..f3a1f9dfa6 100644
--- a/examples/webkit/webkit-guide/_index.html
+++ b/examples/webkit/webkit-guide/_index.html
@@ -298,7 +298,7 @@ entered (localStorage), but credit-card data s/b absent
<div id="feedcloseX" class="feedclose t_button">X</div>
<form id="feedform" action="http://doc.qt.nokia.com/docFeedbck/feedback.php" method="get">
<p id="noteHead">Thank you for giving your feedback.</p> <p class="note">Make sure it is related to this specific page. For more general bugs and
- requests, please use the <a href="http://bugreports.qt.nokia.com/secure/Dashboard.jspa">Qt Bug Tracker</a>.</p>
+ requests, please use the <a href="http://bugreports.qt-project.org/secure/Dashboard.jspa">Qt Bug Tracker</a>.</p>
<p><textarea id="feedbox" name="feedText" rows="5" cols="40"></textarea></p>
<p><input id="feedsubmit" class="feedclose" type="submit" name="feedback" /></p>
</form>
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index 1aa8ae5544..6a8045ab3b 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -24,7 +24,7 @@ CMAKE_PARTIAL_MODULE_DEPS = $$replace(CMAKE_MODULE_DEPS, ";", ";Qt5::")
CMAKE_QT_INSTALL_PREFIX = $$replace($$list($$[QT_INSTALL_PREFIX]), \\\\, /)/
CMAKE_QT_INSTALL_PREFIX_ESCAPED = "^$$re_escape($$CMAKE_QT_INSTALL_PREFIX)"
-CMAKE_INCLUDE_DIR = $$[QT_INSTALL_HEADERS]
+CMAKE_INCLUDE_DIR = $$replace($$list($$[QT_INSTALL_HEADERS]), \\\\, /)/
contains(CMAKE_INCLUDE_DIR, "$${CMAKE_QT_INSTALL_PREFIX_ESCAPED}.*") {
CMAKE_INCLUDE_DIR = $$replace(CMAKE_INCLUDE_DIR, "$$CMAKE_QT_INSTALL_PREFIX_ESCAPED", )
} else {
diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf
index aa706393a5..5d8684bf00 100644
--- a/mkspecs/features/default_pre.prf
+++ b/mkspecs/features/default_pre.prf
@@ -46,6 +46,10 @@ CONFIG = lex yacc warn_on debug uic resources $$CONFIG
} else {
error("Failed to run: $$MSG")
}
+
+ # Let qmake know about the unexpectedly appearing cache file.
+ contains(QTFWD, -cache-module-fwd):_QMAKE_CACHE_ = $$QMAKE_SYNCQT_OUTDIR/.qmake.cache
+
unset(QTFWD)
unset(PRO_BASENAME)
}
diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf
index ad6990657b..98cdab121f 100644
--- a/mkspecs/features/qt_module_config.prf
+++ b/mkspecs/features/qt_module_config.prf
@@ -116,10 +116,8 @@ embedded:DEPENDPATH += ;$$EMBEDDED_H
#install directives
load(qt_installs)
-unix {
- CONFIG += create_libtool create_pc explicitlib
- QMAKE_LIBTOOL_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
- QMAKE_PRL_LIBDIR = $$[QT_RAW_INSTALL_LIBS] ### XXX
+unix|win32-g++* {
+ CONFIG += create_pc
QMAKE_PKGCONFIG_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
QMAKE_PKGCONFIG_INCDIR = $$[QT_RAW_INSTALL_HEADERS]/$$TARGET
QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_RAW_INSTALL_HEADERS]
@@ -130,17 +128,15 @@ unix {
lib_replace.replace = $$[QT_RAW_INSTALL_LIBS]
prefix_replace.match = $$QT_BUILD_TREE
prefix_replace.replace = $$[QT_RAW_INSTALL_PREFIX]
- QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
- QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
QMAKE_PKGCONFIG_INSTALL_REPLACE += include_replace lib_replace prefix_replace
}
-win32-g++* {
- CONFIG += create_pc
- QMAKE_PKGCONFIG_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
- QMAKE_PKGCONFIG_INCDIR = $$[QT_RAW_INSTALL_HEADERS]/$$TARGET
- QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_RAW_INSTALL_HEADERS]
- QMAKE_PKGCONFIG_DESTDIR = pkgconfig
+unix {
+ CONFIG += create_libtool explicitlib
+ QMAKE_PRL_LIBDIR = $$[QT_RAW_INSTALL_LIBS] ### XXX
+ QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
+ QMAKE_LIBTOOL_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
+ QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
}
contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
diff --git a/mkspecs/features/testcocoon.prf b/mkspecs/features/testcocoon.prf
index e6ad733540..523497dba1 100644
--- a/mkspecs/features/testcocoon.prf
+++ b/mkspecs/features/testcocoon.prf
@@ -11,10 +11,10 @@ TARGET_BASENAME = $$basename(QMAKE_RESOLVED_TARGET)
# --cs-output defines the name to give to the execution report (.csexe).
TESTCOCOON_COVERAGE_OPTIONS = \
--cs-qt4 \
- --cs-exclude-file-regex=\'(^|[/\\\\])ui_.*\\.h\$\$\' \
--cs-exclude-file-regex=\'(^|[/\\\\])(qrc|moc)_.*\\.cpp\$\$\' \
--cs-exclude-file-regex=\'.*\\.moc\$\$\' \
--cs-exclude-file-regex=\'.*\\.g\$\$\' \
+ --cs-exclude-file-regex=\'.*\\.h\$\$\' \
--cs-output=\'$$TARGET_BASENAME\' # name of the csexe file (execution report)
# The .csmes file should be placed alongside the .so or binary.
diff --git a/mkspecs/macx-xcode/qmake.conf b/mkspecs/macx-xcode/qmake.conf
index 4cb462696e..de14562039 100644
--- a/mkspecs/macx-xcode/qmake.conf
+++ b/mkspecs/macx-xcode/qmake.conf
@@ -13,8 +13,6 @@ include(../common/mac.conf)
include(../common/gcc-base-macx.conf)
include(../common/g++-macx.conf)
-QMAKE_CC =
-QMAKE_CXX =
QMAKE_LINK =
QMAKE_LINK_C =
QMAKE_LINK_C_SHLIB =
diff --git a/mkspecs/unsupported/win32-g++-cross/qmake.conf b/mkspecs/unsupported/win32-g++-cross/qmake.conf
index 7f41c8aab3..9dcff807fa 100644
--- a/mkspecs/unsupported/win32-g++-cross/qmake.conf
+++ b/mkspecs/unsupported/win32-g++-cross/qmake.conf
@@ -79,6 +79,7 @@ QMAKE_SH = bash
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
QMAKE_COPY = cp
+QMAKE_STREAM_EDITOR = sed
QMAKE_COPY_DIR = cp -R
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm -f
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index c1f0ac3307..641e4109ff 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -79,6 +79,7 @@ QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_DIR_SEP = /
QMAKE_QMAKE ~= s,\\\\,/,
QMAKE_COPY = cp
+ QMAKE_STREAM_EDITOR = sed
QMAKE_COPY_DIR = cp -r
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 16af49311b..d9835932d6 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -73,7 +73,7 @@ CPPFLAGS = -g -I. -Igenerators -Igenerators/unix -Igenerators/win32 \
-Igenerators/mac -Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \
+ -I$(BUILD_PATH)/src/corelib/global \
-I$(SOURCE_PATH)/tools/shared \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 767237fcfc..f640216036 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -33,9 +33,7 @@ CFLAGS_BARE = -c -Fo./ \
$(CFLAGS_EXTRA) \
-I. -Igenerators -Igenerators\unix -Igenerators\win32 -Igenerators\mac -Igenerators\integrity \
-I$(BUILD_PATH)\include -I$(BUILD_PATH)\include\QtCore -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION) -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
- -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION) -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
- -I$(BUILD_PATH)\src\corelib\xml \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
-I$(SOURCE_PATH)\tools\shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \
diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++
index 585061ed26..57e6c1aa4e 100644
--- a/qmake/Makefile.win32-g++
+++ b/qmake/Makefile.win32-g++
@@ -2,12 +2,42 @@ ifeq "$(SOURCE_PATH)" ""
SOURCE_PATH = ..
endif
-#cmd version
-
ifeq "$(BUILD_PATH)" ""
BUILD_PATH = ..
endif
+CORESRC = $(SOURCE_PATH)/src/corelib
+TOOLSRC = $(SOURCE_PATH)/tools
+QMKSRC = $(SOURCE_PATH)/qmake
+
+# SHELL is the full path of sh.exe, unless
+# 1) it is found in the current directory
+# 2) it is not found at all
+# 3) it is overridden on the command line with an existing file
+# ... otherwise it is always sh.exe. Specifically, SHELL from the
+# environment has no effect.
+#
+# This check will fail if SHELL is explicitly set to a not
+# sh-compatible shell. This is not a problem, because configure.exe
+# will not do that.
+ifeq ($(SHELL), sh.exe)
+ ifeq ($(wildcard $(CURDIR)/sh.exe), )
+ SH = 0
+ else
+ SH = 1
+ endif
+else
+ SH = 1
+endif
+
+ifeq ($(SH), 1)
+ COPY = cp
+ DEL = rm -f
+else
+ COPY = copy
+ DEL = del /f
+endif
+
#
# specific stuff for mingw g++ make
#
@@ -17,9 +47,7 @@ CFLAGS = -c -o$@ -O \
-Igenerators/win32 -Igenerators/mac \
-Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(BUILD_PATH)/src/corelib/global \
- -I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
-I$(SOURCE_PATH)/tools/shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
@@ -101,16 +129,16 @@ QTOBJS= \
qmake.exe: $(OBJS) $(QTOBJS)
$(LINKQMAKE)
- -copy qmake.exe $(BUILD_PATH)\bin\qmake.exe
+ -$(COPY) qmake.exe $(BUILD_PATH)\bin\qmake.exe
Makefile: Makefile.win32-g++
@echo "Out of date, please rerun configure"
clean::
- -del $(OBJS) $(QTOBJS) $(ADDCLEAN)
+ -$(DEL) $(OBJS) $(QTOBJS) $(ADDCLEAN)
distclean:: clean
- -del qmake
+ -$(DEL) qmake.exe
.c.o:
$(CXX) $(CFLAGS) $<
@@ -118,227 +146,11 @@ distclean:: clean
.cpp.o:
$(CXX) $(CXXFLAGS) $<
-qconfig.o: $(BUILD_PATH)/src/corelib/global/qconfig.cpp
- $(CXX) $(CXXFLAGS) $(BUILD_PATH)/src/corelib/global/qconfig.cpp
-
-qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
-
-qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
-
-qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
-
-qurl.o: $(SOURCE_PATH)/src/corelib/io/qurl.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qurl.cpp
-
-qtextstream.o: $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
-
-qdatastream.o: $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
-
-qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
-
-qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
-
-qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
-
-qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
-
-qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
-
-qhash.o: $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
-
-qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
-
-qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
-
-qvsnprintf.o: $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
-
-qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
-
-qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
-
-qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
-
-qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
-
-qlocale_tools.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
-
-qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
-
-quuid.o: $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
-
-qbuffer.o: $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
-
-qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
-
-qlinkedlist.o: $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
-
-qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
-
-qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
-
-qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
-
-qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
-
-qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
-
-qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
-
-qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
-
-qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
-
-qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
-
-qfsfileengine_iterator.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
-
-qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
-
-qregexp.o: $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
-
-qvector.o: $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
-
-qbitarray.o: $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
-
-qdir.o: $(SOURCE_PATH)/src/corelib/io/qdir.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdir.cpp
-
-qdiriterator.o: $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
-
-qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
-
-qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
-
-qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
-
-qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
-
-qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
-
-qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
-
-qmap.o: $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
-
-makefile.o: $(SOURCE_PATH)/qmake/generators/makefile.cpp
- $(CXX) $(CXXFLAGS) generators/makefile.cpp
-
-unixmake.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake.cpp
-
-unixmake2.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake2.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake2.cpp
-
-winmakefile.o: $(SOURCE_PATH)/qmake/generators/win32/winmakefile.cpp
- $(CXX) $(CXXFLAGS) generators/win32/winmakefile.cpp
-
-borland_bmake.o: $(SOURCE_PATH)/qmake/generators/win32/borland_bmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/borland_bmake.cpp
-
-mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp
- $(CXX) $(CXXFLAGS) generators/win32/mingw_make.cpp
-
-msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp
-
-msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp
-
-msvc_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp
-
-msvc_vcxproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcxproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcxproj.cpp
-
-msbuild_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msbuild_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msbuild_objectmodel.cpp
-
-registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
-
-gbuild.o: $(SOURCE_PATH)/qmake/generators/integrity/gbuild.cpp
- $(CXX) $(CXXFLAGS) generators/integrity/gbuild.cpp
-
-project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) project.cpp
-
-meta.o: $(SOURCE_PATH)/qmake/meta.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) meta.cpp
-
-main.o: $(SOURCE_PATH)/qmake/main.cpp $(SOURCE_PATH)/qmake/project.h
- $(CXX) $(CXXFLAGS) main.cpp
-
-option.o: $(SOURCE_PATH)/qmake/option.cpp $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) option.cpp
-
-property.o: $(SOURCE_PATH)/qmake/property.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) property.cpp
-
-projectgenerator.o: $(SOURCE_PATH)/qmake/generators/projectgenerator.cpp
- $(CXX) $(CXXFLAGS) generators/projectgenerator.cpp
-
-pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp
- $(CXX) $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp
-
-makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp
- $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp
-
-metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp
- $(CXX) $(CXXFLAGS) generators/metamakefile.cpp
-
-xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp
- $(CXX) $(CXXFLAGS) generators/xmloutput.cpp
-
-qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
-
-qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
+QTVPATH = $(TOOLSRC)/shared/windows:$(CORESRC)/global:$(CORESRC)/kernel:$(CORESRC)/tools:$(CORESRC)/codecs:$(CORESRC)/io:$(CORESRC)/xml:$(CORESRC)/plugin:$(BUILD_PATH)/src/corelib/global
+VPATH = $(QMKSRC):$(QMKSRC)/generators:$(QMKSRC)/generators/unix:$(QMKSRC)/generators/mac:$(QMKSRC)/generators/win32:$(QMKSRC)/generators/integrity:$(QTVPATH)
-qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
+project.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
+meta.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
+main.o: $(QMKSRC)/project.h
+option.o: $(QMKSRC)/option.h
+property.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh
deleted file mode 100644
index 6dfb486375..0000000000
--- a/qmake/Makefile.win32-g++-sh
+++ /dev/null
@@ -1,343 +0,0 @@
-ifeq "$(SOURCE_PATH)" ""
-SOURCE_PATH = ..
-endif
-
-#sh version
-
-ifeq "$(BUILD_PATH)" ""
-BUILD_PATH = ..
-endif
-
-#
-# specific stuff for mingw g++ make
-#
-CXX = g++
-CFLAGS = -c -o$@ -O \
- -I. -Igenerators -Igenerators/unix \
- -Igenerators/win32 -Igenerators/mac \
- -Igenerators/integrity \
- -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(BUILD_PATH)/src/corelib/global \
- -I$(BUILD_PATH)/src/corelib/xml \
- -I$(SOURCE_PATH)/mkspecs/win32-g++ \
- -I$(SOURCE_PATH)/tools/shared \
- -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
- -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
- -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
- -DQT_BOOTSTRAPPED
-CXXFLAGS = $(CFLAGS)
-LFLAGS = -static-libgcc -s
-LIBS = -lole32 -luuid -ladvapi32 -lkernel32
-LINKQMAKE = g++ $(LFLAGS) -o qmake.exe $(OBJS) $(QTOBJS) $(LIBS)
-ADDCLEAN =
-
-
-#qmake code
-OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \
- option.o winmakefile.o projectgenerator.o property.o meta.o \
- makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
- borland_bmake.o msvc_nmake.o msvc_vcproj.o msvc_vcxproj.o \
- msvc_objectmodel.o msbuild_objectmodel.o registry.o gbuild.o
-
-ifdef QMAKE_OPENSOURCE_EDITION
-CFLAGS += -DQMAKE_OPENSOURCE_EDITION
-endif
-
-#qt code
-QTOBJS= \
- qbitarray.o \
- qbuffer.o \
- qbytearray.o \
- qcryptographichash.o \
- qvsnprintf.o \
- qbytearraymatcher.o \
- qconfig.o \
- qdatetime.o \
- qdir.o \
- qdiriterator.o \
- qfile.o \
- qtemporaryfile.o \
- qfileinfo.o \
- qabstractfileengine.o \
- qfilesystementry.o \
- qfilesystemengine.o \
- qfilesystemengine_win.o \
- qfilesystemiterator_win.o \
- qfsfileengine.o \
- qfsfileengine_iterator.o \
- qfsfileengine_win.o \
- qglobal.o \
- qhash.o \
- qiodevice.o \
- qlibraryinfo.o \
- qlist.o \
- qlinkedlist.o \
- qlocale.o \
- qlocale_tools.o \
- qlocale_win.o \
- qmalloc.o \
- qmap.o \
- qregexp.o \
- qtextcodec.o \
- qutfcodec.o \
- qstring.o \
- qstringlist.o \
- qsystemlibrary.o \
- qsystemerror.o \
- qtextstream.o \
- quuid.o \
- qvector.o \
- qurl.o \
- qsettings.o \
- qsettings_win.o \
- qvariant.o \
- qmetatype.o \
- qxmlstream.o \
- qxmlutils.o \
- qnumeric.o \
- qlogging.o
-
-qmake.exe: $(OBJS) $(QTOBJS)
- $(LINKQMAKE)
- -cp qmake.exe $(BUILD_PATH)/bin/qmake.exe
-
-Makefile: Makefile.win32-g++-sh
- @echo "Out of date, please rerun configure"
-
-clean::
- -del $(OBJS) $(QTOBJS) $(ADDCLEAN)
-
-distclean:: clean
- -del qmake
-
-.c.o:
- $(CXX) $(CFLAGS) $<
-
-.cpp.o:
- $(CXX) $(CXXFLAGS) $<
-
-qconfig.o: $(BUILD_PATH)/src/corelib/global/qconfig.cpp
- $(CXX) $(CXXFLAGS) $(BUILD_PATH)/src/corelib/global/qconfig.cpp
-
-qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
-
-qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
-
-qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
-
-qurl.o: $(SOURCE_PATH)/src/corelib/io/qurl.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qurl.cpp
-
-qtextstream.o: $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
-
-qdatastream.o: $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
-
-qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
-
-qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
-
-qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
-
-qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
-
-qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
-
-qhash.o: $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
-
-qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
-
-qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
-
-qvsnprintf.o: $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
-
-qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
-
-qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
-
-qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
-
-qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
-
-qlocale_tools.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
-
-qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
-
-quuid.o: $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
-
-qbuffer.o: $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
-
-qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
-
-qlinkedlist.o: $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
-
-qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
-
-qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
-
-qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
-
-qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
-
-qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
-
-qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
-
-qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
-
-qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
-
-qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
-
-qfsfileengine_iterator.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
-
-qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
-
-qregexp.o: $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
-
-qvector.o: $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
-
-qbitarray.o: $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
-
-qdir.o: $(SOURCE_PATH)/src/corelib/io/qdir.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdir.cpp
-
-qdiriterator.o: $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
-
-qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
-
-qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
-
-qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
-
-qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
-
-qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
-
-qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
-
-qmap.o: $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
-
-makefile.o: $(SOURCE_PATH)/qmake/generators/makefile.cpp
- $(CXX) $(CXXFLAGS) generators/makefile.cpp
-
-unixmake.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake.cpp
-
-unixmake2.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake2.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake2.cpp
-
-winmakefile.o: $(SOURCE_PATH)/qmake/generators/win32/winmakefile.cpp
- $(CXX) $(CXXFLAGS) generators/win32/winmakefile.cpp
-
-borland_bmake.o: $(SOURCE_PATH)/qmake/generators/win32/borland_bmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/borland_bmake.cpp
-
-mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp
- $(CXX) $(CXXFLAGS) generators/win32/mingw_make.cpp
-
-msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp
-
-msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp
-
-msvc_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp
-
-msvc_vcxproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcxproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcxproj.cpp
-
-msbuild_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msbuild_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msbuild_objectmodel.cpp
-
-registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
-
-gbuild.o: $(SOURCE_PATH)/qmake/generators/integrity/gbuild.cpp
- $(CXX) $(CXXFLAGS) generators/integrity/gbuild.cpp
-
-project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) project.cpp
-
-meta.o: $(SOURCE_PATH)/qmake/meta.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) meta.cpp
-
-main.o: $(SOURCE_PATH)/qmake/main.cpp $(SOURCE_PATH)/qmake/project.h
- $(CXX) $(CXXFLAGS) main.cpp
-
-option.o: $(SOURCE_PATH)/qmake/option.cpp $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) option.cpp
-
-property.o: $(SOURCE_PATH)/qmake/property.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) property.cpp
-
-projectgenerator.o: $(SOURCE_PATH)/qmake/generators/projectgenerator.cpp
- $(CXX) $(CXXFLAGS) generators/projectgenerator.cpp
-
-pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp
- $(CXX) $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp
-
-makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp
- $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp
-
-metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp
- $(CXX) $(CXXFLAGS) generators/metamakefile.cpp
-
-xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp
- $(CXX) $(CXXFLAGS) generators/xmloutput.cpp
-
-qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
-
-qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
-
-qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 2f6b30fe12..70efff0bcd 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -508,6 +508,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
//HEADER
const int pbVersion = pbuilderVersion();
+ QStringList buildConfigGroups;
+ buildConfigGroups << "PROJECT";
+ if (pbVersion >= 46)
+ buildConfigGroups << "TARGET";
+
t << "// !$*UTF8*$!" << "\n"
<< "{" << "\n"
<< "\t" << writeSettings("archiveVersion", "1", SettingsNoQuote) << ";" << "\n"
@@ -810,7 +815,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS",
- "QMAKE_LIBS", QString() };
+ "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", QString() };
for(int i = 0; !libs[i].isNull(); i++) {
tmp = project->values(libs[i]);
for(int x = 0; x < tmp.count();) {
@@ -1014,28 +1019,22 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n"
<< "\t\t" << "};" << "\n";
}
- { //INSTALL BUILDPHASE (copy)
+ if (!project->isEmpty("DESTDIR")) {
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
- QString destDir = Option::output_dir;
- if (!project->isEmpty("QMAKE_ORIG_DESTDIR"))
- destDir = project->first("QMAKE_ORIG_DESTDIR");
+ QString destDir = project->first("DESTDIR");
destDir = fixForOutput(destDir);
destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath();
- project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
+ project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
t << "\t\t" << phase_key << " = {\n"
+ << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n"
<< "\t\t\t" << writeSettings("name", "Project Copy") << ";" << "\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("dstPath", escapeFilePath(destDir)) << ";" << "\n"
- << "\t\t\t" << writeSettings("dstSubfolderSpec", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("files", keyFor("QMAKE_PBX_TARGET_COPY_FILE"), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("files", QStringList(), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("inputPaths", QStringList(), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("outputPaths", QStringList(), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t" << "};\n"
- << "\t\t" << keyFor("QMAKE_PBX_TARGET_COPY_FILE") << " = {\n"
- << "\t\t\t" << writeSettings("fileRef", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << "settings = {\n"
- << "\t\t\t" << "};\n"
+ << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n"
+ << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";" << "\n"
<< "\t\t" << "};\n";
}
//BUNDLE_DATA BUILDPHASE (copy)
@@ -1113,6 +1112,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Preprocessor Steps") << ";" << "\n"
<< "\t\t\t" << writeSettings("productName", "Qt Preprocessor Steps") << ";" << "\n"
<< "\t\t\t" << writeSettings("productReference", keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")) << ";" << "\n";
+ if (pbVersion >= 46)
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST"), SettingsNoQuote) << ";" << "\n";
if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE"))
t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n";
else
@@ -1217,28 +1218,30 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t\t" << writeSettings("CPLUSPLUS", fixForOutput(findProgram(cCompiler))) << ";" << "\n";
}
- t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
- << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
- << "\t\t\t\t" << writeSettings("OPTIMIZATION_CFLAGS", QStringList(), SettingsAsList, 5) << ";" << "\n";
- {
- QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
- const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
- for(int i = 0; i < prl_defines.size(); ++i)
- cflags += "-D" + prl_defines.at(i);
- const QStringList &defines = project->values("DEFINES");
- for(int i = 0; i < defines.size(); ++i)
- cflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
- }
- {
- QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
- const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
- for(int i = 0; i < prl_defines.size(); ++i)
- cxxflags += "-D" + prl_defines.at(i);
- const QStringList &defines = project->values("DEFINES");
- for(int i = 0; i < defines.size(); ++i)
- cxxflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ if (pbVersion < 46) {
+ t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("OPTIMIZATION_CFLAGS", QStringList(), SettingsAsList, 5) << ";" << "\n";
+ {
+ QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ {
+ QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cxxflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cxxflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ }
}
t << "\t\t\t\t" << writeSettings("LEXFLAGS", fixListForOutput("QMAKE_LEXFLAGS")) << ";" << "\n"
<< "\t\t\t\t" << writeSettings("YACCFLAGS", fixListForOutput("QMAKE_YACCFLAGS")) << ";" << "\n"
@@ -1298,7 +1301,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
+ fixListForOutput("QMAKE_LFLAGS")
+ fixListForOutput("QMAKE_LIBDIR_FLAGS")
+ fixListForOutput("QMAKE_FRAMEWORKPATH_FLAGS")
- + fixListForOutput("QMAKE_LIBS"),
+ + fixListForOutput("QMAKE_LIBS")
+ + fixListForOutput("QMAKE_LIBS_PRIVATE"),
SettingsAsList, 6) << ";" << "\n";
}
if(!project->isEmpty("DESTDIR")) {
@@ -1318,7 +1322,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
project->isActiveConfig("lib_bundle"))
t << "\t\t\t\t" << writeSettings("FRAMEWORK_VERSION", project->first("QMAKE_FRAMEWORK_VERSION")) << ";" << "\n";
}
- if(!project->isEmpty("COMPAT_FRAMEWORKPATH"))
+ if (pbVersion < 46 && !project->isEmpty("COMPAT_FRAMEWORKPATH"))
t << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n";
if(!project->isEmpty("COMPAT_VERSION"))
t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("COMPAT_VERSION")) << ";" << "\n";
@@ -1334,7 +1338,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
else
t << "\t\t\t\t" << writeSettings("SYMROOT", fixForOutput(qmake_getpwd())) << ";" << "\n";
#endif
- {
+ if (pbVersion < 46) {
QStringList archs;
if(project->isActiveConfig("x86"))
archs += "i386";
@@ -1385,6 +1389,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("dependencies", project->values("QMAKE_PBX_TARGET_DEPENDS"), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << writeSettings("productReference", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n"
<< "\t\t\t" << writeSettings("shouldUseHeadermap", "1", SettingsNoQuote) << ";" << "\n";
+ if (pbVersion >= 46)
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_TARGET"), SettingsNoQuote) << ";" << "\n";
if(pbVersion >= 38)
t << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";" << "\n";
if(project->first("TEMPLATE") == "app") {
@@ -1493,6 +1499,16 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
settings.insert(name, value);
}
}
+ if (pbVersion >= 46) {
+ if (project->first("TEMPLATE") == "app") {
+ settings.insert("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET")));
+ } else {
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
+ lib.prepend("lib");
+ settings.insert("PRODUCT_NAME", escapeFilePath(lib));
+ }
+ }
QString name;
if(pbVersion >= 42)
@@ -1500,42 +1516,121 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
else
name = (as_release ? "Deployment" : "Development");
if(pbVersion >= 42) {
- QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name);
- project->values("QMAKE_PBX_BUILDCONFIGS").append(key);
+ for (int i = 0; i < buildConfigGroups.size(); i++) {
+ QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i));
+ project->values("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i)).append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << "buildSettings = {" << "\n";
+ for (QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
+ t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
+ if (pbVersion >= 46) {
+ if (buildConfigGroups.at(i) == QLatin1String("PROJECT")) {
+ t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n";
+ {
+ QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ {
+ QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cxxflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cxxflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ if (!project->isActiveConfig("staticlib")) {
+ t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
+ fixListForOutput("SUBLIBS")
+ + fixListForOutput("QMAKE_LFLAGS")
+ + fixListForOutput("QMAKE_LIBDIR_FLAGS")
+ + fixListForOutput("QMAKE_FRAMEWORKPATH_FLAGS")
+ + fixListForOutput("QMAKE_LIBS")
+ + fixListForOutput("QMAKE_LIBS_PRIVATE"),
+ SettingsAsList, 6) << ";" << "\n";
+ }
+ {
+ QStringList archs;
+ if (project->isActiveConfig("x86"))
+ archs += "i386";
+ if (project->isActiveConfig("ppc")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "ppc";
+ }
+ if (project->isActiveConfig("ppc64")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "ppc64";
+ }
+ if (project->isActiveConfig("x86_64")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "x86_64";
+ }
+ if (!archs.isEmpty())
+ t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";" << "\n";
+ }
+ } else {
+ if (project->first("TEMPLATE") == "app") {
+ if (pbVersion < 38 && project->isActiveConfig("app_bundle"))
+ t << "\t\t\t\t" << writeSettings("WRAPPER_SUFFIX", "app") << ";" << "\n";
+ t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n";
+ } else {
+ if (!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib"))
+ t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "STATIC") << ";" << "\n";
+ else
+ t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "DYNAMIC") << ";" << "\n";
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
+ lib.prepend("lib");
+ t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";" << "\n";
+ }
+ }
+ t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << writeSettings("name", name) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ }
+
+ QString key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name);
+ if (project->isActiveConfig("debug") != (bool)as_release) {
+ project->values("QMAKE_PBX_BUILDSTYLES").append(key);
+ active_buildstyle = name;
+ } else if (pbVersion >= 42) {
+ project->values("QMAKE_PBX_BUILDSTYLES").append(key);
+ }
t << "\t\t" << key << " = {" << "\n"
- << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << "buildSettings = {" << "\n";
for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
- t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
+ t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n";
t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n"
<< "\t\t\t" << writeSettings("name", name) << ";" << "\n"
<< "\t\t" << "};" << "\n";
}
-
- QString key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name);
- if(project->isActiveConfig("debug") != (bool)as_release) {
- project->values("QMAKE_PBX_BUILDSTYLES").append(key);
- active_buildstyle = name;
- } else if(pbVersion >= 42) {
- project->values("QMAKE_PBX_BUILDSTYLES").append(key);
- }
- t << "\t\t" << key << " = {" << "\n"
- << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << "buildSettings = {" << "\n";
- for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
- t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n";
- t << "\t\t\t" << "};" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n"
- << "\t\t\t" << writeSettings("name", name) << ";" << "\n"
- << "\t\t" << "};" << "\n";
}
if(pbVersion >= 42) {
- t << "\t\t" << keyFor("QMAKE_PBX_BUILDCONFIG_LIST") << " = {" << "\n"
- << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_PBX_BUILDCONFIGS"), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n"
- << "\t\t" << "};" << "\n";
+ for (int i = 0; i < buildConfigGroups.size(); i++) {
+ t << "\t\t" << keyFor("QMAKE_PBX_BUILDCONFIG_LIST_" + buildConfigGroups.at(i)) << " = {" << "\n"
+ << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i)), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
}
//ROOT
t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
@@ -1544,7 +1639,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("isa", "PBXProject", SettingsNoQuote) << ";" << "\n"
<< "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_PBX_ROOT_GROUP")) << ";" << "\n";
if(pbVersion >= 42)
- t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST")) << ";" << "\n";
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_PROJECT")) << ";" << "\n";
t << "\t\t\t" << writeSettings("projectDirPath", QStringList()) << ";" << "\n"
<< "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";" << "\n"
<< "\t\t" << "};" << "\n";
@@ -1693,7 +1788,11 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
#ifdef Q_OS_DARWIN
ret = QLatin1String("34");
QCFType<CFURLRef> cfurl;
- OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl);
+ // Check for XCode 4 first
+ OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.dt.Xcode"), 0, 0, &cfurl);
+ // Now check for XCode 3
+ if (err == kLSApplicationNotFoundErr)
+ err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl);
if (err == noErr) {
QCFType<CFBundleRef> bundle = CFBundleCreate(0, cfurl);
if (bundle) {
@@ -1703,7 +1802,9 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
QStringList versions = QCFString::toQString(str).split(QLatin1Char('.'));
int versionMajor = versions.at(0).toInt();
int versionMinor = versions.at(1).toInt();
- if (versionMajor >= 2) {
+ if (versionMajor >= 3) {
+ ret = QLatin1String("46");
+ } else if (versionMajor >= 2) {
ret = QLatin1String("42");
} else if (versionMajor == 1 && versionMinor >= 5) {
ret = QLatin1String("39");
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 45cb250fe1..63367f116a 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -2235,10 +2235,6 @@ QString MakefileGenerator::buildArgs(const QString &outdir)
ret += " -win32";
}
- //configs
- for(QStringList::Iterator it = Option::user_configs.begin();
- it != Option::user_configs.end(); ++it)
- ret += " -config " + (*it);
//arguments
for(QStringList::Iterator it = Option::before_user_vars.begin();
it != Option::before_user_vars.end(); ++it) {
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index b9fec023ab..39dd4ab797 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -238,25 +238,21 @@ MakefileGenerator
//initialize the base
QHash<QString, QStringList> basevars;
+ QStringList basecfgs;
if(!project->isEmpty(build + ".CONFIG"))
- basevars["CONFIG"] += project->values(build + ".CONFIG");
- basevars["CONFIG"] += build;
- basevars["CONFIG"] += "build_pass";
+ basecfgs = project->values(build + ".CONFIG");
+ basecfgs += build;
+ basecfgs += "build_pass";
basevars["BUILD_PASS"] = QStringList(build);
QStringList buildname = project->values(build + ".name");
basevars["BUILD_NAME"] = (buildname.isEmpty() ? QStringList(build) : buildname);
//create project
- QMakeProject *build_proj = new QMakeProject(project->properties(), basevars);
+ QMakeProject *build_proj = new QMakeProject(project->properties());
+ build_proj->setExtraVars(basevars);
+ build_proj->setExtraConfigs(basecfgs);
- //all the user configs must be set again afterwards (for .pro tests and for .prf tests)
- const QStringList old_after_user_config = Option::after_user_configs;
- const QStringList old_user_config = Option::user_configs;
- Option::after_user_configs += basevars["CONFIG"];
- Option::user_configs += basevars["CONFIG"];
build_proj->read(project->projectFile());
- Option::after_user_configs = old_after_user_config;
- Option::user_configs = old_user_config;
//done
return createMakefileGenerator(build_proj);
diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp
index a2eb45ef40..9a181a43f5 100644
--- a/qmake/generators/projectgenerator.cpp
+++ b/qmake/generators/projectgenerator.cpp
@@ -344,8 +344,6 @@ ProjectGenerator::writeMakefile(QTextStream &t)
t << "######################################################################" << endl;
t << "# Automatically generated by qmake (" << qmake_version() << ") " << QDateTime::currentDateTime().toString() << endl;
t << "######################################################################" << endl << endl;
- if(!Option::user_configs.isEmpty())
- t << "CONFIG += " << Option::user_configs.join(" ") << endl;
int i;
for(i = 0; i < Option::before_user_vars.size(); ++i)
t << Option::before_user_vars[i] << endl;
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index a26be16f78..9d983ffc66 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -649,6 +649,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
t << "DEF_FILE = " << varList("DEF_FILE") << endl;
t << "RES_FILE = " << varList("RES_FILE") << endl; // Not on mingw, can't see why not though...
t << "COPY = " << var("QMAKE_COPY") << endl;
+ t << "SED = " << var("QMAKE_STREAM_EDITOR") << endl;
t << "COPY_FILE = " << var("QMAKE_COPY_FILE") << endl;
t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl;
t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
@@ -852,7 +853,22 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
}
if(!ret.isEmpty())
ret += "\n\t";
- ret += "-$(INSTALL_FILE) \"" + pkgConfigFileName(true) + "\" \"" + dst_pc + "\"";
+ const QString replace_rule("QMAKE_PKGCONFIG_INSTALL_REPLACE");
+ if (project->isEmpty(replace_rule)
+ || project->isActiveConfig("no_sed_meta_install")
+ || project->isEmpty("QMAKE_STREAM_EDITOR")) {
+ ret += "-$(INSTALL_FILE) \"" + pkgConfigFileName(true) + "\" \"" + dst_pc + "\"";
+ } else {
+ ret += "-$(SED)";
+ QStringList replace_rules = project->values(replace_rule);
+ for (int r = 0; r < replace_rules.size(); ++r) {
+ const QString match = project->first(replace_rules.at(r) + ".match"),
+ replace = project->first(replace_rules.at(r) + ".replace");
+ if (!match.isEmpty() /*&& match != replace*/)
+ ret += " -e \"s," + match + "," + replace + ",g\"";
+ }
+ ret += " \"" + pkgConfigFileName(true) + "\" >\"" + dst_pc + "\"";
+ }
if(!uninst.isEmpty())
uninst.append("\n\t");
uninst.append("-$(DEL_FILE) \"" + dst_pc + "\"");
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 54cf9f9bdf..985afaa8e8 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -163,7 +163,7 @@ int runQMake(int argc, char **argv)
fn = fn.right(fn.length() - di - 1);
}
- if (!Option::prepareProject()) {
+ if (!Option::prepareProject(fn)) {
exit_val = 3;
break;
}
diff --git a/qmake/option.cpp b/qmake/option.cpp
index 0c649fdd77..4e0d5b198e 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -91,8 +91,6 @@ QString Option::output_dir;
Option::QMAKE_RECURSIVE Option::recursive = Option::QMAKE_RECURSIVE_DEFAULT;
QStringList Option::before_user_vars;
QStringList Option::after_user_vars;
-QStringList Option::user_configs;
-QStringList Option::after_user_configs;
QString Option::user_template;
QString Option::user_template_prefix;
QStringList Option::shellPath;
@@ -116,6 +114,7 @@ bool Option::mkfile::do_dep_heuristics = true;
bool Option::mkfile::do_preprocess = false;
bool Option::mkfile::do_stub_makefile = false;
bool Option::mkfile::do_cache = true;
+QString Option::mkfile::project_root;
QString Option::mkfile::project_build_root;
QString Option::mkfile::cachefile;
QStringList Option::mkfile::project_files;
@@ -219,6 +218,8 @@ bool usage(const char *a0)
int
Option::parseCommandLine(int argc, char **argv, int skip)
{
+ QStringList user_configs;
+
bool before = true;
for(int x = skip; x < argc; x++) {
if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */
@@ -303,7 +304,7 @@ Option::parseCommandLine(int argc, char **argv, int skip)
} else if(opt == "nr" || opt == "norecursive") {
Option::recursive = Option::QMAKE_RECURSIVE_NO;
} else if(opt == "config") {
- Option::user_configs += argv[++x];
+ user_configs += argv[++x];
} else {
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
@@ -376,6 +377,9 @@ Option::parseCommandLine(int argc, char **argv, int skip)
}
}
+ if (!user_configs.isEmpty())
+ Option::before_user_vars += "CONFIG += " + user_configs.join(" ");
+
return Option::QMAKE_CMDLINE_SUCCESS;
}
@@ -576,7 +580,48 @@ void Option::applyHostMode()
}
}
-bool Option::prepareProject()
+QStringList Option::mkspecPaths()
+{
+ QStringList ret;
+ const QString concat = QLatin1String("/mkspecs");
+
+ QByteArray qmakepath = qgetenv("QMAKEPATH");
+ if (!qmakepath.isEmpty()) {
+ const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
+ for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
+ ret << ((*it) + concat);
+ }
+ ret << Option::mkfile::project_build_root + concat;
+ if (!Option::mkfile::project_root.isEmpty())
+ ret << Option::mkfile::project_root + concat;
+ ret << QLibraryInfo::location(QLibraryInfo::HostDataPath) + concat;
+ return ret;
+}
+
+bool Option::resolveSpec(QString *spec)
+{
+ QString qmakespec = fixEnvVariables(*spec);
+ if (qmakespec.isEmpty())
+ qmakespec = "default";
+ if (QDir::isRelativePath(qmakespec)) {
+ QStringList mkspec_roots = mkspecPaths();
+ debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
+ mkspec_roots.join("::").toLatin1().constData());
+ for (QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
+ QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
+ if (QFile::exists(mkspec)) {
+ *spec = mkspec;
+ return true;
+ }
+ }
+ fprintf(stderr, "Could not find mkspecs for your QMAKESPEC(%s) after trying:\n\t%s\n",
+ qmakespec.toLatin1().constData(), mkspec_roots.join("\n\t").toLatin1().constData());
+ return false;
+ }
+ return true;
+}
+
+bool Option::prepareProject(const QString &pfile)
{
mkfile::project_build_root.clear();
if (mkfile::do_cache) {
@@ -601,6 +646,37 @@ bool Option::prepareProject()
}
}
no_cache:
+
+ QString srcpath = (pfile != "-")
+ ? QDir::cleanPath(QFileInfo(pfile).absolutePath()) : qmake_getpwd();
+ if (srcpath != output_dir || mkfile::project_build_root.isEmpty()) {
+ QDir srcdir(srcpath);
+ QDir dstdir(output_dir);
+ do {
+ if (!mkfile::project_build_root.isEmpty()) {
+ // If we already know the build root, just match up the source root with it.
+ if (dstdir.path() == mkfile::project_build_root) {
+ mkfile::project_root = srcdir.path();
+ break;
+ }
+ } else {
+ // Look for mkspecs/ in source and build. First to win determines the root.
+ if (dstdir.exists("mkspecs") || srcdir.exists("mkspecs")) {
+ mkfile::project_build_root = dstdir.path();
+ mkfile::project_root = srcdir.path();
+ if (mkfile::project_root == mkfile::project_build_root)
+ mkfile::project_root.clear();
+ break;
+ }
+ }
+ } while (!srcdir.isRoot() && srcdir.cdUp() && !dstdir.isRoot() && dstdir.cdUp());
+ } else {
+ mkfile::project_root.clear();
+ }
+
+ if (!resolveSpec(&Option::mkfile::qmakespec))
+ return false;
+
return true;
}
diff --git a/qmake/option.h b/qmake/option.h
index b812f14a49..23384877fd 100644
--- a/qmake/option.h
+++ b/qmake/option.h
@@ -109,7 +109,8 @@ struct Option
//both of these must be called..
static int init(int argc=0, char **argv=0); //parse cmdline
static void applyHostMode();
- static bool prepareProject();
+ static QStringList mkspecPaths();
+ static bool prepareProject(const QString &pfile);
static bool postProcessProject(QMakeProject *);
enum StringFixFlags {
@@ -173,7 +174,7 @@ struct Option
static int warn_level;
enum QMAKE_RECURSIVE { QMAKE_RECURSIVE_DEFAULT, QMAKE_RECURSIVE_YES, QMAKE_RECURSIVE_NO };
static QMAKE_RECURSIVE recursive;
- static QStringList before_user_vars, after_user_vars, user_configs, after_user_configs;
+ static QStringList before_user_vars, after_user_vars;
enum HOST_MODE { HOST_UNKNOWN_MODE, HOST_UNIX_MODE, HOST_WIN_MODE, HOST_MACX_MODE };
static HOST_MODE host_mode;
enum TARG_MODE { TARG_UNKNOWN_MODE, TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE,
@@ -203,6 +204,7 @@ struct Option
static bool do_dep_heuristics;
static bool do_preprocess;
static bool do_stub_makefile;
+ static QString project_root;
static QString project_build_root;
static QString cachefile;
static int cachefile_depth;
@@ -212,6 +214,7 @@ struct Option
private:
static int parseCommandLine(int, char **, int=0);
+ static bool resolveSpec(QString *spec);
};
inline QString fixEnvVariables(const QString &x) { return Option::fixString(x, Option::FixEnvVars); }
diff --git a/qmake/project.cpp b/qmake/project.cpp
index bfd4511f2f..f6e26254c5 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -530,9 +530,10 @@ static void qmake_error_msg(const QString &msg)
*/
QStringList qmake_feature_paths(QMakeProperty *prop=0)
{
+ const QString mkspecs_concat = QLatin1String("/mkspecs");
+ const QString base_concat = QLatin1String("/features");
QStringList concat;
{
- const QString base_concat = QLatin1String("/features");
switch(Option::target_mode) {
case Option::TARG_MACX_MODE: //also a unix
concat << base_concat + QLatin1String("/mac");
@@ -549,7 +550,7 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
}
concat << base_concat;
}
- const QString mkspecs_concat = QLatin1String("/mkspecs");
+
QStringList feature_roots;
QByteArray mkspec_path = qgetenv("QMAKEFEATURES");
if(!mkspec_path.isNull())
@@ -574,19 +575,17 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
feature_roots << ((*it) + mkspecs_concat + (*concat_it));
}
}
- if(!Option::mkfile::qmakespec.isEmpty())
- feature_roots << Option::mkfile::qmakespec + QLatin1String("/features");
if(!Option::mkfile::qmakespec.isEmpty()) {
+ // The spec is already platform-dependent, so no subdirs here.
+ feature_roots << Option::mkfile::qmakespec + base_concat;
+
QFileInfo specfi(Option::mkfile::qmakespec);
- QDir specdir(specfi.absoluteFilePath());
- while(!specdir.isRoot()) {
- if(!specdir.cdUp() || specdir.isRoot())
- break;
- if(QFile::exists(specdir.path() + QLatin1String("/features"))) {
+ if (!specfi.isRoot()) {
+ QDir specdir(specfi.absolutePath());
+ if (specdir.exists(QLatin1String("features"))) {
for(QStringList::Iterator concat_it = concat.begin();
concat_it != concat.end(); ++concat_it)
feature_roots << (specdir.path() + (*concat_it));
- break;
}
}
}
@@ -597,21 +596,6 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
return feature_roots;
}
-QStringList qmake_mkspec_paths()
-{
- QStringList ret;
- const QString concat = QLatin1String("/mkspecs");
- QByteArray qmakepath = qgetenv("QMAKEPATH");
- if (!qmakepath.isEmpty()) {
- const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
- for(QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
- ret << ((*it) + concat);
- }
- ret << QLibraryInfo::location(QLibraryInfo::HostDataPath) + concat;
-
- return ret;
-}
-
QMakeProject::~QMakeProject()
{
if(own_prop)
@@ -630,10 +614,8 @@ QMakeProject::~QMakeProject()
void
-QMakeProject::init(QMakeProperty *p, const QHash<QString, QStringList> *vars)
+QMakeProject::init(QMakeProperty *p)
{
- if(vars)
- base_vars = *vars;
if(!p) {
prop = new QMakeProperty;
own_prop = true;
@@ -647,7 +629,8 @@ QMakeProject::init(QMakeProperty *p, const QHash<QString, QStringList> *vars)
QMakeProject::QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *vars)
{
- init(p->properties(), vars ? vars : &p->variables());
+ init(p->properties());
+ base_vars = vars ? *vars : p->variables();
for(QHash<QString, FunctionBlock*>::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) {
it.value()->ref();
replaceFunctions.insert(it.key(), it.value());
@@ -1174,6 +1157,8 @@ QMakeProject::parse(const QString &t, QHash<QString, QStringList> &place, int nu
}
if(var == "REQUIRES") // special case to get communicated to backends!
doProjectCheckReqs(vallist, place);
+ else if (var == "_QMAKE_CACHE_")
+ Option::mkfile::cachefile = varlist.isEmpty() ? QString() : varlist.at(0);
}
return true;
}
@@ -1286,50 +1271,7 @@ QMakeProject::read(uchar cmd)
Option::output_dir.mid(Option::mkfile::project_build_root.length()).count('/');
}
if (cmd & ReadSetup) { // parse mkspec
- QString qmakespec = fixEnvVariables(Option::mkfile::qmakespec);
- QStringList mkspec_roots = qmake_mkspec_paths();
- debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
- mkspec_roots.join("::").toLatin1().constData());
- if(qmakespec.isEmpty()) {
- for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
- QString mkspec = (*it) + QLatin1String("/default");
- QFileInfo default_info(mkspec);
- if(default_info.exists() && default_info.isDir()) {
- qmakespec = mkspec;
- break;
- }
- }
- if(qmakespec.isEmpty()) {
- fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n");
- return false;
- }
- Option::mkfile::qmakespec = qmakespec;
- }
-
- if(QDir::isRelativePath(qmakespec)) {
- if (QFile::exists(Option::output_dir+"/"+qmakespec+"/qmake.conf")) {
- qmakespec = Option::mkfile::qmakespec = QFileInfo(Option::output_dir+"/"+qmakespec).absoluteFilePath();
- } else if (QFile::exists(qmakespec+"/qmake.conf")) {
- Option::mkfile::qmakespec = QFileInfo(Option::mkfile::qmakespec).absoluteFilePath();
- } else {
- bool found_mkspec = false;
- for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
- QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
- if(QFile::exists(mkspec)) {
- found_mkspec = true;
- Option::mkfile::qmakespec = qmakespec = mkspec;
- break;
- }
- }
- if(!found_mkspec) {
- fprintf(stderr, "Could not find mkspecs for your QMAKESPEC(%s) after trying:\n\t%s\n",
- qmakespec.toLatin1().constData(), mkspec_roots.join("\n\t").toLatin1().constData());
- return false;
- }
- }
- }
-
- // parse qmake configuration
+ QString qmakespec = Option::mkfile::qmakespec;
while(qmakespec.endsWith(QLatin1Char('/')))
qmakespec.truncate(qmakespec.length()-1);
QString spec = qmakespec + QLatin1String("/qmake.conf");
@@ -1349,6 +1291,10 @@ QMakeProject::read(uchar cmd)
vars = base_vars; // start with the base
+ for (QHash<QString, QStringList>::ConstIterator it = extra_vars.constBegin();
+ it != extra_vars.constEnd(); ++it)
+ vars.insert(it.key(), it.value());
+
if(cmd & ReadFeatures) {
debug_msg(1, "Processing default_pre: %s", vars["CONFIG"].join("::").toLatin1().constData());
doProjectInclude("default_pre", IncludeFlagFeature, vars);
@@ -1375,12 +1321,12 @@ QMakeProject::read(uchar cmd)
}
}
- //commandline configs
- if ((cmd & ReadSetup) && !Option::user_configs.isEmpty()) {
- parser.file = "(configs)";
+ // After user configs, to override them
+ if (!extra_configs.isEmpty()) {
+ parser.file = "(extra configs)";
parser.from_file = false;
parser.line_no = 1; //really arg count now.. duh
- parse("CONFIG += " + Option::user_configs.join(" "), vars);
+ parse("CONFIG += " + extra_configs.join(" "), vars);
}
if(cmd & ReadProFile) { // parse project file
@@ -1406,12 +1352,14 @@ QMakeProject::read(uchar cmd)
}
}
- //after configs (set in BUILDS)
- if ((cmd & ReadSetup) && !Option::after_user_configs.isEmpty()) {
- parser.file = "(configs)";
+ // Again, to ensure the project does not mess with us.
+ // Specifically, do not allow a project to override debug/release within a
+ // debug_and_release build pass - it's too late for that at this point anyway.
+ if (!extra_configs.isEmpty()) {
+ parser.file = "(extra configs)";
parser.from_file = false;
parser.line_no = 1; //really arg count now.. duh
- parse("CONFIG += " + Option::after_user_configs.join(" "), vars);
+ parse("CONFIG += " + extra_configs.join(" "), vars);
}
if(cmd & ReadFeatures) {
diff --git a/qmake/project.h b/qmake/project.h
index ce90be035f..6422ed1f32 100644
--- a/qmake/project.h
+++ b/qmake/project.h
@@ -84,7 +84,8 @@ class QMakeProject
QString pfile, cfile;
QMakeProperty *prop;
void reset();
- QHash<QString, QStringList> vars, base_vars;
+ QStringList extra_configs;
+ QHash<QString, QStringList> vars, base_vars, extra_vars;
bool parse(const QString &text, QHash<QString, QStringList> &place, int line_count=1);
enum IncludeStatus {
@@ -105,19 +106,19 @@ class QMakeProject
bool doProjectCheckReqs(const QStringList &deps, QHash<QString, QStringList> &place);
bool doVariableReplace(QString &str, QHash<QString, QStringList> &place);
QStringList doVariableReplaceExpand(const QString &str, QHash<QString, QStringList> &place, bool *ok=0);
- void init(QMakeProperty *, const QHash<QString, QStringList> *);
+ void init(QMakeProperty *);
QStringList &values(const QString &v, QHash<QString, QStringList> &place);
void validateModes();
void resolveSpec(QString *spec, const QString &qmakespec);
public:
- QMakeProject() { init(0, 0); }
- QMakeProject(QMakeProperty *p) { init(p, 0); }
+ QMakeProject(QMakeProperty *p = 0) { init(p); }
QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *nvars=0);
- QMakeProject(const QHash<QString, QStringList> &nvars) { init(0, &nvars); }
- QMakeProject(QMakeProperty *p, const QHash<QString, QStringList> &nvars) { init(p, &nvars); }
~QMakeProject();
+ void setExtraVars(const QHash<QString, QStringList> &_vars) { extra_vars = _vars; }
+ void setExtraConfigs(const QStringList &_cfgs) { extra_configs = _cfgs; }
+
enum { ReadProFile=0x01, ReadSetup=0x02, ReadFeatures=0x04, ReadAll=0xFF };
inline bool parse(const QString &text) { return parse(text, vars); }
bool read(const QString &project, uchar cmd=ReadAll);
diff --git a/qmake/property.cpp b/qmake/property.cpp
index 7cb689ed7e..8ed9462c60 100644
--- a/qmake/property.cpp
+++ b/qmake/property.cpp
@@ -49,8 +49,6 @@
QT_BEGIN_NAMESPACE
-QStringList qmake_mkspec_paths(); //project.cpp
-
static const struct {
const char *name;
QLibraryInfo::LibraryLocation loc;
@@ -124,7 +122,7 @@ QMakeProperty::value(QString v, bool just_check)
if (!val.isNull())
return val;
else if(v == "QMAKE_MKSPECS")
- return qmake_mkspec_paths().join(Option::dirlist_sep);
+ return Option::mkspecPaths().join(Option::dirlist_sep);
else if(v == "QMAKE_VERSION")
return qmake_version();
#ifdef QT_VERSION_STR
diff --git a/src/3rdparty/pcre/AUTHORS b/src/3rdparty/pcre/AUTHORS
new file mode 100644
index 0000000000..ba4753d858
--- /dev/null
+++ b/src/3rdparty/pcre/AUTHORS
@@ -0,0 +1,45 @@
+THE MAIN PCRE LIBRARY
+---------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2012 University of Cambridge
+All rights reserved
+
+
+PCRE JUST-IN-TIME COMPILATION SUPPORT
+-------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2012 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2012 Zoltan Herczeg
+All rights reserved.
+
+
+THE C++ WRAPPER LIBRARY
+-----------------------
+
+Written by: Google Inc.
+
+Copyright (c) 2007-2012 Google Inc
+All rights reserved
+
+####
diff --git a/src/3rdparty/pcre/COPYING b/src/3rdparty/pcre/COPYING
new file mode 100644
index 0000000000..58eed01b61
--- /dev/null
+++ b/src/3rdparty/pcre/COPYING
@@ -0,0 +1,5 @@
+PCRE LICENCE
+
+Please see the file LICENCE in the PCRE distribution for licensing details.
+
+End
diff --git a/src/3rdparty/pcre/LICENCE b/src/3rdparty/pcre/LICENCE
new file mode 100644
index 0000000000..5ce31a828d
--- /dev/null
+++ b/src/3rdparty/pcre/LICENCE
@@ -0,0 +1,92 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+The basic library functions are written in C and are freestanding. Also
+included in the distribution is a set of C++ wrapper functions, and a
+just-in-time compiler that can be used to optimize pattern matching. These
+are both optional features that can be omitted when the library is built.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2012 University of Cambridge
+All rights reserved.
+
+
+PCRE JUST-IN-TIME COMPILATION SUPPORT
+-------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2012 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2012 Zoltan Herczeg
+All rights reserved.
+
+
+THE C++ WRAPPER FUNCTIONS
+-------------------------
+
+Contributed by: Google Inc.
+
+Copyright (c) 2007-2012, Google Inc.
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the name of Google
+ Inc. nor the names of their contributors may be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End
diff --git a/src/3rdparty/pcre/pcre.h b/src/3rdparty/pcre/pcre.h
new file mode 100644
index 0000000000..712bd3d714
--- /dev/null
+++ b/src/3rdparty/pcre/pcre.h
@@ -0,0 +1,503 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_H
+#define _PCRE_H
+
+/* The current PCRE version information. */
+
+#define PCRE_MAJOR 8
+#define PCRE_MINOR 30
+#define PCRE_PRERELEASE
+#define PCRE_DATE 2012-02-04
+
+/* When an application links to a PCRE DLL in Windows, the symbols that are
+imported have to be identified as such. When building PCRE, the appropriate
+export setting is defined in pcre_internal.h, which includes this file. So we
+don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
+
+#if defined(_WIN32) && !defined(PCRE_STATIC)
+# ifndef PCRE_EXP_DECL
+# define PCRE_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN __declspec(dllimport)
+# endif
+# endif
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCRE_EXP_DECL
+# ifdef __cplusplus
+# define PCRE_EXP_DECL extern "C"
+# else
+# define PCRE_EXP_DECL extern
+# endif
+#endif
+
+#ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN
+# endif
+#endif
+
+/* Have to include stdlib.h in order to ensure that size_t is defined;
+it is needed here for malloc. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options. Some are compile-time only, some are run-time only, and some are
+both, so we keep them all distinct. However, almost all the bits in the options
+word are now used. In the long run, we may have to re-use some of the
+compile-time only bits for runtime options, or vice versa. In the comments
+below, "compile", "exec", and "DFA exec" mean that the option is permitted to
+be set for those functions; "used in" means that an option may be set only for
+compile, but is subsequently referenced in exec and/or DFA exec. Any of the
+compile-time options may be inspected during studying (and therefore JIT
+compiling). */
+
+#define PCRE_CASELESS 0x00000001 /* Compile */
+#define PCRE_MULTILINE 0x00000002 /* Compile */
+#define PCRE_DOTALL 0x00000004 /* Compile */
+#define PCRE_EXTENDED 0x00000008 /* Compile */
+#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
+#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
+#define PCRE_EXTRA 0x00000040 /* Compile */
+#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
+#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
+#define PCRE_UNGREEDY 0x00000200 /* Compile */
+#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
+#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
+#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
+#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
+#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
+#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
+#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
+#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
+#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
+#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
+#define PCRE_DUPNAMES 0x00080000 /* Compile */
+#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
+#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
+#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
+#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
+#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
+#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
+#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
+
+/* Exec-time and get/set-time error codes */
+
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
+#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+#define PCRE_ERROR_MATCHLIMIT (-8)
+#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+#define PCRE_ERROR_DFA_UITEM (-16)
+#define PCRE_ERROR_DFA_UCOND (-17)
+#define PCRE_ERROR_DFA_UMLIMIT (-18)
+#define PCRE_ERROR_DFA_WSSIZE (-19)
+#define PCRE_ERROR_DFA_RECURSE (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE (-23)
+#define PCRE_ERROR_BADOFFSET (-24)
+#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
+#define PCRE_ERROR_RECURSELOOP (-26)
+#define PCRE_ERROR_JIT_STACKLIMIT (-27)
+#define PCRE_ERROR_BADMODE (-28)
+#define PCRE_ERROR_BADENDIANNESS (-29)
+
+/* Specific error codes for UTF-8 validity checks */
+
+#define PCRE_UTF8_ERR0 0
+#define PCRE_UTF8_ERR1 1
+#define PCRE_UTF8_ERR2 2
+#define PCRE_UTF8_ERR3 3
+#define PCRE_UTF8_ERR4 4
+#define PCRE_UTF8_ERR5 5
+#define PCRE_UTF8_ERR6 6
+#define PCRE_UTF8_ERR7 7
+#define PCRE_UTF8_ERR8 8
+#define PCRE_UTF8_ERR9 9
+#define PCRE_UTF8_ERR10 10
+#define PCRE_UTF8_ERR11 11
+#define PCRE_UTF8_ERR12 12
+#define PCRE_UTF8_ERR13 13
+#define PCRE_UTF8_ERR14 14
+#define PCRE_UTF8_ERR15 15
+#define PCRE_UTF8_ERR16 16
+#define PCRE_UTF8_ERR17 17
+#define PCRE_UTF8_ERR18 18
+#define PCRE_UTF8_ERR19 19
+#define PCRE_UTF8_ERR20 20
+#define PCRE_UTF8_ERR21 21
+
+/* Specific error codes for UTF-16 validity checks */
+
+#define PCRE_UTF16_ERR0 0
+#define PCRE_UTF16_ERR1 1
+#define PCRE_UTF16_ERR2 2
+#define PCRE_UTF16_ERR3 3
+#define PCRE_UTF16_ERR4 4
+
+/* Request types for pcre_fullinfo() */
+
+#define PCRE_INFO_OPTIONS 0
+#define PCRE_INFO_SIZE 1
+#define PCRE_INFO_CAPTURECOUNT 2
+#define PCRE_INFO_BACKREFMAX 3
+#define PCRE_INFO_FIRSTBYTE 4
+#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
+#define PCRE_INFO_FIRSTTABLE 5
+#define PCRE_INFO_LASTLITERAL 6
+#define PCRE_INFO_NAMEENTRYSIZE 7
+#define PCRE_INFO_NAMECOUNT 8
+#define PCRE_INFO_NAMETABLE 9
+#define PCRE_INFO_STUDYSIZE 10
+#define PCRE_INFO_DEFAULT_TABLES 11
+#define PCRE_INFO_OKPARTIAL 12
+#define PCRE_INFO_JCHANGED 13
+#define PCRE_INFO_HASCRORLF 14
+#define PCRE_INFO_MINLENGTH 15
+#define PCRE_INFO_JIT 16
+#define PCRE_INFO_JITSIZE 17
+
+/* Request types for pcre_config(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_CONFIG_UTF8 0
+#define PCRE_CONFIG_NEWLINE 1
+#define PCRE_CONFIG_LINK_SIZE 2
+#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
+#define PCRE_CONFIG_MATCH_LIMIT 4
+#define PCRE_CONFIG_STACKRECURSE 5
+#define PCRE_CONFIG_UNICODE_PROPERTIES 6
+#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
+#define PCRE_CONFIG_BSR 8
+#define PCRE_CONFIG_JIT 9
+#define PCRE_CONFIG_UTF16 10
+#define PCRE_CONFIG_JITTARGET 11
+
+/* Request types for pcre_study(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_STUDY_JIT_COMPILE 0x0001
+
+/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
+these bits, just add new ones on the end, in order to remain compatible. */
+
+#define PCRE_EXTRA_STUDY_DATA 0x0001
+#define PCRE_EXTRA_MATCH_LIMIT 0x0002
+#define PCRE_EXTRA_CALLOUT_DATA 0x0004
+#define PCRE_EXTRA_TABLES 0x0008
+#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
+#define PCRE_EXTRA_MARK 0x0020
+#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
+
+/* Types */
+
+struct real_pcre; /* declaration; the definition is private */
+typedef struct real_pcre pcre;
+
+struct real_pcre16; /* declaration; the definition is private */
+typedef struct real_pcre16 pcre16;
+
+struct real_pcre_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre_jit_stack pcre_jit_stack;
+
+struct real_pcre16_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre16_jit_stack pcre16_jit_stack;
+
+/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
+a 16 bit wide signed data type. Otherwise it can be a dummy data type since
+pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
+#endif
+
+#ifndef PCRE_SPTR16
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
+#endif
+
+/* When PCRE is compiled as a C++ library, the subject pointer type can be
+replaced with a custom type. For conventional use, the public interface is a
+const char *. */
+
+#ifndef PCRE_SPTR
+#define PCRE_SPTR const char *
+#endif
+
+/* The structure for passing additional data to pcre_exec(). This is defined in
+such as way as to be extensible. Always add new fields at the end, in order to
+remain compatible. */
+
+typedef struct pcre_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ unsigned char **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre_extra;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre16_extra;
+
+/* The structure for passing out data via the pcre_callout_function. We use a
+structure so that new fields can be added on the end in future versions,
+without changing the API of the function, thereby allowing old clients to work
+without modification. */
+
+typedef struct pcre_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const unsigned char *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre_callout_block;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR16 subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre16_callout_block;
+
+/* Indirection for store get and free functions. These can be set to
+alternative malloc/free functions if required. Special ones are used in the
+non-recursive case for "frames". There is also an optional callout function
+that is triggered by the (?) regex item. For Virtual Pascal, these definitions
+have to take another form. */
+
+#ifndef VPCOMPAT
+PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_free)(void *);
+PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
+
+PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_free)(void *);
+PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
+#else /* VPCOMPAT */
+PCRE_EXP_DECL void *pcre_malloc(size_t);
+PCRE_EXP_DECL void pcre_free(void *);
+PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre_stack_free(void *);
+PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
+
+PCRE_EXP_DECL void *pcre16_malloc(size_t);
+PCRE_EXP_DECL void pcre16_free(void *);
+PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre16_stack_free(void *);
+PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
+#endif /* VPCOMPAT */
+
+/* User defined callback which provides a stack just before the match starts. */
+
+typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
+typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL int pcre_config(int, void *);
+PCRE_EXP_DECL int pcre16_config(int, void *);
+PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
+ int *, int, const char *, char *, int);
+PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
+ const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
+ int, int, int, int *, int);
+PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int);
+PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
+PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
+ int *, int, const char *, const char **);
+PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
+PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
+ char **, char **);
+PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
+ PCRE_UCHAR16 **, PCRE_UCHAR16 **);
+PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
+ const char **);
+PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
+ const char ***);
+PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
+ PCRE_SPTR16 **);
+PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
+PCRE_EXP_DECL int pcre_refcount(pcre *, int);
+PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
+PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
+PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
+PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
+PCRE_EXP_DECL const char *pcre_version(void);
+PCRE_EXP_DECL const char *pcre16_version(void);
+
+/* Utility functions for byte order swaps. */
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
+ PCRE_SPTR16, int, int *, int);
+
+/* JIT compiler related functions. */
+
+PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
+PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
+PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
+PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
+PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
+ pcre_jit_callback, void *);
+PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
+ pcre16_jit_callback, void *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/src/3rdparty/pcre/pcre16_byte_order.c b/src/3rdparty/pcre/pcre16_byte_order.c
new file mode 100644
index 0000000000..11d2973a3d
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_byte_order.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_byte_order.c"
+
+/* End of pcre16_byte_order.c */
diff --git a/src/3rdparty/pcre/pcre16_chartables.c b/src/3rdparty/pcre/pcre16_chartables.c
new file mode 100644
index 0000000000..7c0ff35f5e
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_chartables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_chartables.c"
+
+/* End of pcre16_chartables.c */
diff --git a/src/3rdparty/pcre/pcre16_compile.c b/src/3rdparty/pcre/pcre16_compile.c
new file mode 100644
index 0000000000..e499b67087
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_compile.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_compile.c"
+
+/* End of pcre16_compile.c */
diff --git a/src/3rdparty/pcre/pcre16_config.c b/src/3rdparty/pcre/pcre16_config.c
new file mode 100644
index 0000000000..b52138764f
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_config.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_config.c"
+
+/* End of pcre16_config.c */
diff --git a/src/3rdparty/pcre/pcre16_dfa_exec.c b/src/3rdparty/pcre/pcre16_dfa_exec.c
new file mode 100644
index 0000000000..2ba740e972
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_dfa_exec.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_dfa_exec.c"
+
+/* End of pcre16_dfa_exec.c */
diff --git a/src/3rdparty/pcre/pcre16_exec.c b/src/3rdparty/pcre/pcre16_exec.c
new file mode 100644
index 0000000000..7417b1770c
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_exec.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_exec.c"
+
+/* End of pcre16_exec.c */
diff --git a/src/3rdparty/pcre/pcre16_fullinfo.c b/src/3rdparty/pcre/pcre16_fullinfo.c
new file mode 100644
index 0000000000..544dca6ed5
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_fullinfo.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_fullinfo.c"
+
+/* End of pcre16_fullinfo.c */
diff --git a/src/3rdparty/pcre/pcre16_get.c b/src/3rdparty/pcre/pcre16_get.c
new file mode 100644
index 0000000000..3ded08c622
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_get.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_get.c"
+
+/* End of pcre16_get.c */
diff --git a/src/3rdparty/pcre/pcre16_globals.c b/src/3rdparty/pcre/pcre16_globals.c
new file mode 100644
index 0000000000..a136b3d8c2
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_globals.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_globals.c"
+
+/* End of pcre16_globals.c */
diff --git a/src/3rdparty/pcre/pcre16_jit_compile.c b/src/3rdparty/pcre/pcre16_jit_compile.c
new file mode 100644
index 0000000000..ab0cacd764
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_jit_compile.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_jit_compile.c"
+
+/* End of pcre16_jit_compile.c */
diff --git a/src/3rdparty/pcre/pcre16_maketables.c b/src/3rdparty/pcre/pcre16_maketables.c
new file mode 100644
index 0000000000..b1cd1c579d
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_maketables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_maketables.c"
+
+/* End of pcre16_maketables.c */
diff --git a/src/3rdparty/pcre/pcre16_newline.c b/src/3rdparty/pcre/pcre16_newline.c
new file mode 100644
index 0000000000..7fe201400f
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_newline.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_newline.c"
+
+/* End of pcre16_newline.c */
diff --git a/src/3rdparty/pcre/pcre16_ord2utf16.c b/src/3rdparty/pcre/pcre16_ord2utf16.c
new file mode 100644
index 0000000000..9f7db8661f
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_ord2utf16.c
@@ -0,0 +1,95 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF16 string. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert character value to UTF-16 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-16 character in 1 to 2 pcre_uchars.
+
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result - at least 2 pcre_uchars long
+
+Returns: number of characters placed in the buffer
+*/
+
+int
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
+{
+#ifdef SUPPORT_UTF
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+if (cvalue <= 0xffff)
+ {
+ *buffer = (pcre_uchar)cvalue;
+ return 1;
+ }
+
+cvalue -= 0x10000;
+*buffer++ = 0xd800 | (cvalue >> 10);
+*buffer = 0xdc00 | (cvalue & 0x3ff);
+return 2;
+
+#else /* SUPPORT_UTF */
+(void)(cvalue); /* Keep compiler happy; this function won't ever be */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
+return 0;
+#endif /* SUPPORT_UTF */
+}
+
+/* End of pcre16_ord2utf16.c */
diff --git a/src/3rdparty/pcre/pcre16_refcount.c b/src/3rdparty/pcre/pcre16_refcount.c
new file mode 100644
index 0000000000..d3d1543973
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_refcount.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_refcount.c"
+
+/* End of pcre16_refcount.c */
diff --git a/src/3rdparty/pcre/pcre16_string_utils.c b/src/3rdparty/pcre/pcre16_string_utils.c
new file mode 100644
index 0000000000..382c40799f
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_string_utils.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_string_utils.c"
+
+/* End of pcre16_string_utils.c */
diff --git a/src/3rdparty/pcre/pcre16_study.c b/src/3rdparty/pcre/pcre16_study.c
new file mode 100644
index 0000000000..f87de081fc
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_study.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_study.c"
+
+/* End of pcre16_study.c */
diff --git a/src/3rdparty/pcre/pcre16_tables.c b/src/3rdparty/pcre/pcre16_tables.c
new file mode 100644
index 0000000000..d84297093a
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_tables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_tables.c"
+
+/* End of pcre16_tables.c */
diff --git a/src/3rdparty/pcre/pcre16_ucd.c b/src/3rdparty/pcre/pcre16_ucd.c
new file mode 100644
index 0000000000..ee23439a01
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_ucd.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_ucd.c"
+
+/* End of pcre16_ucd.c */
diff --git a/src/3rdparty/pcre/pcre16_utf16_utils.c b/src/3rdparty/pcre/pcre16_utf16_utils.c
new file mode 100644
index 0000000000..7cfdbdd5ee
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_utf16_utils.c
@@ -0,0 +1,129 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a function for converting any UTF-16 character
+strings to host byte order. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert any UTF-16 string to host byte order *
+*************************************************/
+
+/* This function takes an UTF-16 string and converts
+it to host byte order. The length can be explicitly set,
+or automatically detected for zero terminated strings.
+BOMs can be kept or discarded during the conversion.
+Conversion can be done in place (output == input).
+
+Arguments:
+ output the output buffer, its size must be greater
+ or equal than the input string
+ input any UTF-16 string
+ length the number of 16-bit units in the input string
+ can be less than zero for zero terminated strings
+ host_byte_order
+ A non-zero value means the input is in host byte
+ order, which can be dynamically changed by BOMs later.
+ Initially it contains the starting byte order and returns
+ with the last byte order so it can be used for stream
+ processing. It can be NULL, which set the host byte
+ order mode by default.
+ keep_boms for a non-zero value, the BOM (0xfeff) characters
+ are copied as well
+
+Returns: the number of 16-bit units placed into the output buffer,
+ including the zero-terminator
+*/
+
+int
+pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input,
+ int length, int *host_byte_order, int keep_boms)
+{
+#ifdef SUPPORT_UTF
+/* This function converts any UTF-16 string to host byte order and optionally
+removes any Byte Order Marks (BOMS). Returns with the remainig length. */
+int host_bo = host_byte_order != NULL ? *host_byte_order : 1;
+pcre_uchar *optr = (pcre_uchar *)output;
+const pcre_uchar *iptr = (const pcre_uchar *)input;
+const pcre_uchar *end;
+/* The c variable must be unsigned. */
+register pcre_uchar c;
+
+if (length < 0)
+ length = STRLEN_UC(iptr) + 1;
+end = iptr + length;
+
+while (iptr < end)
+ {
+ c = *iptr++;
+ if (c == 0xfeff || c == 0xfffe)
+ {
+ /* Detecting the byte order of the machine is unnecessary, it is
+ enough to know that the UTF-16 string has the same byte order or not. */
+ host_bo = c == 0xfeff;
+ if (keep_boms != 0)
+ *optr++ = 0xfeff;
+ else
+ length--;
+ }
+ else
+ *optr++ = host_bo ? c : ((c >> 8) | (c << 8)); /* Flip bytes if needed. */
+ }
+if (host_byte_order != NULL)
+ *host_byte_order = host_bo;
+
+#else /* SUPPORT_UTF */
+(void)(output); /* Keep picky compilers happy */
+(void)(input);
+(void)(keep_boms);
+#endif /* SUPPORT_UTF */
+return length;
+}
+
+/* End of pcre16_utf16_utils.c */
diff --git a/src/3rdparty/pcre/pcre16_valid_utf16.c b/src/3rdparty/pcre/pcre16_valid_utf16.c
new file mode 100644
index 0000000000..90b9f86770
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_valid_utf16.c
@@ -0,0 +1,146 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF-16 character
+strings. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Validate a UTF-16 string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF-16 string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+From release 8.21 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF16_ERR0 No error
+PCRE_UTF16_ERR1 Missing low surrogate at the end of the string
+PCRE_UTF16_ERR2 Invalid low surrogate
+PCRE_UTF16_ERR3 Isolated low surrogate
+PCRE_UTF16_ERR4 Not allowed character
+
+Arguments:
+ string points to the string
+ length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
+
+Returns: = 0 if the string is a valid UTF-16 string
+ > 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
+{
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
+register pcre_uchar c;
+
+if (length < 0)
+ {
+ for (p = string; *p != 0; p++);
+ length = p - string;
+ }
+
+for (p = string; length-- > 0; p++)
+ {
+ c = *p;
+
+ if ((c & 0xf800) != 0xd800)
+ {
+ /* Normal UTF-16 code point. Neither high nor low surrogate. */
+
+ /* This is probably a BOM from a different byte-order.
+ Regardless, the string is rejected. */
+ if (c == 0xfffe)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR4;
+ }
+ }
+ else if ((c & 0x0400) == 0)
+ {
+ /* High surrogate. */
+
+ /* Must be a followed by a low surrogate. */
+ if (length == 0)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR1;
+ }
+ p++;
+ length--;
+ if ((*p & 0xfc00) != 0xdc00)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR2;
+ }
+ }
+ else
+ {
+ /* Isolated low surrogate. Always an error. */
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR3;
+ }
+ }
+
+#else /* SUPPORT_UTF */
+(void)(string); /* Keep picky compilers happy */
+(void)(length);
+#endif /* SUPPORT_UTF */
+
+return PCRE_UTF16_ERR0; /* This indicates success */
+}
+
+/* End of pcre16_valid_utf16.c */
diff --git a/src/3rdparty/pcre/pcre16_version.c b/src/3rdparty/pcre/pcre16_version.c
new file mode 100644
index 0000000000..e991b1a8cf
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_version.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_version.c"
+
+/* End of pcre16_version.c */
diff --git a/src/3rdparty/pcre/pcre16_xclass.c b/src/3rdparty/pcre/pcre16_xclass.c
new file mode 100644
index 0000000000..5aac2a36c6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_xclass.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_xclass.c"
+
+/* End of pcre16_xclass.c */
diff --git a/src/3rdparty/pcre/pcre_byte_order.c b/src/3rdparty/pcre/pcre_byte_order.c
new file mode 100644
index 0000000000..6f5fa742d6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_byte_order.c
@@ -0,0 +1,288 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that tests a compiled pattern to
+see if it was compiled with the opposite endianness. If so, it uses an
+auxiliary local function to flip the appropriate bytes. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Swap byte functions *
+*************************************************/
+
+/* The following functions swap the bytes of a pcre_uint16
+and pcre_uint32 value.
+
+Arguments:
+ value any number
+
+Returns: the byte swapped value
+*/
+
+static pcre_uint32
+swap_uint32(pcre_uint32 value)
+{
+return ((value & 0x000000ff) << 24) |
+ ((value & 0x0000ff00) << 8) |
+ ((value & 0x00ff0000) >> 8) |
+ (value >> 24);
+}
+
+static pcre_uint16
+swap_uint16(pcre_uint16 value)
+{
+return (value >> 8) | (value << 8);
+}
+
+
+/*************************************************
+* Test for a byte-flipped compiled regex *
+*************************************************/
+
+/* This function swaps the bytes of a compiled pattern usually
+loaded form the disk. It also sets the tables pointer, which
+is likely an invalid pointer after reload.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ tables points to the character tables or NULL
+
+Returns: 0 if the swap is successful, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
+ pcre_extra *extra_data, const unsigned char *tables)
+#else
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
+ pcre16_extra *extra_data, const unsigned char *tables)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+pcre_study_data *study;
+#ifndef COMPILE_PCRE8
+pcre_uchar *ptr;
+int length;
+#ifdef SUPPORT_UTF
+BOOL utf;
+BOOL utf16_char;
+#endif /* SUPPORT_UTF */
+#endif /* !COMPILE_PCRE8 */
+
+if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number == MAGIC_NUMBER)
+ {
+ if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+ re->tables = tables;
+ return 0;
+ }
+
+if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+re->magic_number = MAGIC_NUMBER;
+re->size = swap_uint32(re->size);
+re->options = swap_uint32(re->options);
+re->flags = swap_uint16(re->flags);
+re->top_bracket = swap_uint16(re->top_bracket);
+re->top_backref = swap_uint16(re->top_backref);
+re->first_char = swap_uint16(re->first_char);
+re->req_char = swap_uint16(re->req_char);
+re->name_table_offset = swap_uint16(re->name_table_offset);
+re->name_entry_size = swap_uint16(re->name_entry_size);
+re->name_count = swap_uint16(re->name_count);
+re->ref_count = swap_uint16(re->ref_count);
+re->tables = tables;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ {
+ study = (pcre_study_data *)extra_data->study_data;
+ study->size = swap_uint32(study->size);
+ study->flags = swap_uint32(study->flags);
+ study->minlength = swap_uint32(study->minlength);
+ }
+
+#ifndef COMPILE_PCRE8
+ptr = (pcre_uchar *)re + re->name_table_offset;
+length = re->name_count * re->name_entry_size;
+#ifdef SUPPORT_UTF
+utf = (re->options & PCRE_UTF16) != 0;
+utf16_char = FALSE;
+#endif
+
+while(TRUE)
+ {
+ /* Swap previous characters. */
+ while (length-- > 0)
+ {
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+#ifdef SUPPORT_UTF
+ if (utf16_char)
+ {
+ if (HAS_EXTRALEN(ptr[-1]))
+ {
+ /* We know that there is only one extra character in UTF-16. */
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+ }
+ utf16_char = FALSE;
+#endif /* SUPPORT_UTF */
+
+ /* Get next opcode. */
+ length = 0;
+ *ptr = swap_uint16(*ptr);
+ switch (*ptr)
+ {
+ case OP_END:
+ return 0;
+
+#ifdef SUPPORT_UTF
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ if (utf) utf16_char = TRUE;
+#endif
+ /* Fall through. */
+
+ default:
+ length = PRIV(OP_lengths)[*ptr] - 1;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length = 0;
+ break;
+
+ case OP_XCLASS:
+ /* Reverse the size of the XCLASS instance. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ if (LINK_SIZE > 1)
+ {
+ /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ }
+ ptr++;
+ length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
+ *ptr = swap_uint16(*ptr);
+ if ((*ptr & XCL_MAP) != 0)
+ {
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length -= 32/sizeof(pcre_uchar);
+ }
+ break;
+ }
+ ptr++;
+ }
+/* Control should never reach here in 16 bit mode. */
+#endif /* !COMPILE_PCRE8 */
+
+return 0;
+}
+
+/* End of pcre_byte_order.c */
diff --git a/src/3rdparty/pcre/pcre_chartables.c b/src/3rdparty/pcre/pcre_chartables.c
new file mode 100644
index 0000000000..55df49777d
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_chartables.c
@@ -0,0 +1,198 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This file contains character tables that are used when no external tables
+are passed to PCRE by the application that calls it. The tables are used only
+for characters whose code values are less than 256.
+
+This is a default version of the tables that assumes ASCII encoding. A program
+called dftables (which is distributed with PCRE) can be used to build
+alternative versions of this file. This is necessary if you are running in an
+EBCDIC environment, or if you want to default to a different encoding, for
+example ISO-8859-1. When dftables is run, it creates these tables in the
+current locale. If PCRE is configured with --enable-rebuild-chartables, this
+happens automatically.
+
+The following #includes are present because without them gcc 4.x may remove the
+array definition from the final binary if PCRE is built into a static library
+and dead code stripping is activated. This leads to link errors. Pulling in the
+header ensures that the array gets flagged as "someone outside this compilation
+unit might reference this" and so it will always be supplied to the linker. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+const pcre_uint8 PRIV(default_tables)[] = {
+
+/* This table is a lower casing table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table is a case flipping table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table contains bit maps for various character classes. Each map is 32
+bytes long and the bits run from the least significant end of each byte. The
+classes that have their own maps are: space, xdigit, digit, upper, lower, word,
+graph, print, punct, and cntrl. Other classes are built from combinations. */
+
+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
+ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+/* This table identifies various classes of character by individual bits:
+ 0x01 white space character
+ 0x02 letter
+ 0x04 decimal digit
+ 0x08 hexadecimal digit
+ 0x10 alphanumeric or '_'
+ 0x80 regular expression metacharacter or binary zero
+*/
+
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
+ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+/* End of pcre_chartables.c */
diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c
new file mode 100644
index 0000000000..b0c57ca122
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_compile.c
@@ -0,0 +1,8162 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_compile(), along with
+supporting internal functions that are not used by other modules. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK cd /* Block containing newline information */
+#define PSSTART start_pattern /* Field containing processed string start */
+#define PSEND end_pattern /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which
+is also used by pcretest. PCRE_DEBUG is not defined when building a production
+library. We do not need to select pcre16_printint.c specially, because the
+COMPILE_PCREx macro will already be appropriately set. */
+
+#ifdef PCRE_DEBUG
+/* pcre_printint.c should not include any headers */
+#define PCRE_INCLUDED
+#include "pcre_printint.c"
+#undef PCRE_INCLUDED
+#endif
+
+
+/* Macro for setting individual bits in class bitmaps. */
+
+#define SETBIT(a,b) a[b/8] |= (1 << (b%8))
+
+/* Maximum length value to check against when making sure that the integer that
+holds the compiled pattern length does not overflow. We make it a bit less than
+INT_MAX to allow for adding in group terminating bytes, so that we don't have
+to check them every time. */
+
+#define OFLOW_MAX (INT_MAX - 20)
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+/* This value specifies the size of stack workspace that is used during the
+first pre-compile phase that determines how much memory is required. The regex
+is partly compiled into this space, but the compiled parts are discarded as
+soon as they can be, so that hopefully there will never be an overrun. The code
+does, however, check for an overrun. The largest amount I've seen used is 218,
+so this number is very generous.
+
+The same workspace is used during the second, actual compile phase for
+remembering forward references to groups so that they can be filled in at the
+end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
+is 4 there is plenty of room for most patterns. However, the memory can get
+filled up by repetitions of forward references, for example patterns like
+/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so
+that the workspace is expanded using malloc() in this situation. The value
+below is therefore a minimum, and we put a maximum on it for safety. The
+minimum is now also defined in terms of LINK_SIZE so that the use of malloc()
+kicks in at the same number of forward references in all cases. */
+
+#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
+#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
+
+/* The overrun tests check for a slightly smaller size so that they detect the
+overrun before it actually does run off the end of the data block. */
+
+#define WORK_SIZE_SAFETY_MARGIN (100)
+
+/* Private flags added to firstchar and reqchar. */
+
+#define REQ_CASELESS 0x10000000l /* Indicates caselessness */
+#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */
+
+/* Repeated character flags. */
+
+#define UTF_LENGTH 0x10000000l /* The char contains its length. */
+
+/* Table for handling escaped characters in the range '0'-'z'. Positive returns
+are simple data values; negative values are for special things like \d and so
+on. Zero means further processing is needed (for things like \x), or the escape
+is invalid. */
+
+#ifndef EBCDIC
+
+/* This is the "normal" table for ASCII systems or for EBCDIC systems running
+in UTF-8 mode. */
+
+static const short int escapes[] = {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ CHAR_COLON, CHAR_SEMICOLON,
+ CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
+ CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
+ CHAR_COMMERCIAL_AT, -ESC_A,
+ -ESC_B, -ESC_C,
+ -ESC_D, -ESC_E,
+ 0, -ESC_G,
+ -ESC_H, 0,
+ 0, -ESC_K,
+ 0, 0,
+ -ESC_N, 0,
+ -ESC_P, -ESC_Q,
+ -ESC_R, -ESC_S,
+ 0, 0,
+ -ESC_V, -ESC_W,
+ -ESC_X, 0,
+ -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
+ CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
+ CHAR_GRAVE_ACCENT, 7,
+ -ESC_b, 0,
+ -ESC_d, ESC_e,
+ ESC_f, 0,
+ -ESC_h, 0,
+ 0, -ESC_k,
+ 0, 0,
+ ESC_n, 0,
+ -ESC_p, 0,
+ ESC_r, -ESC_s,
+ ESC_tee, 0,
+ -ESC_v, -ESC_w,
+ 0, 0,
+ -ESC_z
+};
+
+#else
+
+/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
+
+static const short int escapes[] = {
+/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
+/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
+/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
+/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
+/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
+/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
+/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
+/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
+/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
+/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
+/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
+/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
+/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
+/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
+/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
+/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P,
+/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
+/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
+/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
+/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
+};
+#endif
+
+
+/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
+searched linearly. Put all the names into a single string, in order to reduce
+the number of relocations when a shared library is dynamically linked. The
+string is built from string macros so that it works in UTF-8 mode on EBCDIC
+platforms. */
+
+typedef struct verbitem {
+ int len; /* Length of verb name */
+ int op; /* Op when no arg, or -1 if arg mandatory */
+ int op_arg; /* Op when arg present, or -1 if not allowed */
+} verbitem;
+
+static const char verbnames[] =
+ "\0" /* Empty name is a shorthand for MARK */
+ STRING_MARK0
+ STRING_ACCEPT0
+ STRING_COMMIT0
+ STRING_F0
+ STRING_FAIL0
+ STRING_PRUNE0
+ STRING_SKIP0
+ STRING_THEN;
+
+static const verbitem verbs[] = {
+ { 0, -1, OP_MARK },
+ { 4, -1, OP_MARK },
+ { 6, OP_ACCEPT, -1 },
+ { 6, OP_COMMIT, -1 },
+ { 1, OP_FAIL, -1 },
+ { 4, OP_FAIL, -1 },
+ { 5, OP_PRUNE, OP_PRUNE_ARG },
+ { 4, OP_SKIP, OP_SKIP_ARG },
+ { 4, OP_THEN, OP_THEN_ARG }
+};
+
+static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+
+
+/* Tables of names of POSIX character classes and their lengths. The names are
+now all in a single string, to reduce the number of relocations when a shared
+library is dynamically loaded. The list of lengths is terminated by a zero
+length entry. The first three must be alpha, lower, upper, as this is assumed
+for handling case independence. */
+
+static const char posix_names[] =
+ STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
+ STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
+ STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
+ STRING_word0 STRING_xdigit;
+
+static const pcre_uint8 posix_name_lengths[] = {
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+
+/* Table of class bit maps for each POSIX class. Each class is formed from a
+base map, with an optional addition or removal of another map. Then, for some
+classes, there is some additional tweaking: for [:blank:] the vertical space
+characters are removed, and for [:alpha:] and [:alnum:] the underscore
+character is removed. The triples in the table consist of the base map offset,
+second map offset or -1 if no second map, and a non-negative value for map
+addition or a negative value for map subtraction (if there are two maps). The
+absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
+remove vertical space characters, 2 => remove underscore. */
+
+static const int posix_class_maps[] = {
+ cbit_word, cbit_digit, -2, /* alpha */
+ cbit_lower, -1, 0, /* lower */
+ cbit_upper, -1, 0, /* upper */
+ cbit_word, -1, 2, /* alnum - word without underscore */
+ cbit_print, cbit_cntrl, 0, /* ascii */
+ cbit_space, -1, 1, /* blank - a GNU extension */
+ cbit_cntrl, -1, 0, /* cntrl */
+ cbit_digit, -1, 0, /* digit */
+ cbit_graph, -1, 0, /* graph */
+ cbit_print, -1, 0, /* print */
+ cbit_punct, -1, 0, /* punct */
+ cbit_space, -1, 0, /* space */
+ cbit_word, -1, 0, /* word - a Perl extension */
+ cbit_xdigit,-1, 0 /* xdigit */
+};
+
+/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class
+substitutes must be in the order of the names, defined above, and there are
+both positive and negative cases. NULL means no substitute. */
+
+#ifdef SUPPORT_UCP
+static const pcre_uchar string_PNd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pNd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXsp[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXsp[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXwd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXwd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *substitutes[] = {
+ string_PNd, /* \D */
+ string_pNd, /* \d */
+ string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
+ string_pXsp, /* \s */
+ string_PXwd, /* \W */
+ string_pXwd /* \w */
+};
+
+static const pcre_uchar string_pL[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLl[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLu[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXan[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_h[] = {
+ CHAR_BACKSLASH, CHAR_h, '\0' };
+static const pcre_uchar string_pXps[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PL[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLl[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLu[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXan[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_H[] = {
+ CHAR_BACKSLASH, CHAR_H, '\0' };
+static const pcre_uchar string_PXps[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *posix_substitutes[] = {
+ string_pL, /* alpha */
+ string_pLl, /* lower */
+ string_pLu, /* upper */
+ string_pXan, /* alnum */
+ NULL, /* ascii */
+ string_h, /* blank */
+ NULL, /* cntrl */
+ string_pNd, /* digit */
+ NULL, /* graph */
+ NULL, /* print */
+ NULL, /* punct */
+ string_pXps, /* space */ /* NOTE: Xps is POSIX space */
+ string_pXwd, /* word */
+ NULL, /* xdigit */
+ /* Negated cases */
+ string_PL, /* ^alpha */
+ string_PLl, /* ^lower */
+ string_PLu, /* ^upper */
+ string_PXan, /* ^alnum */
+ NULL, /* ^ascii */
+ string_H, /* ^blank */
+ NULL, /* ^cntrl */
+ string_PNd, /* ^digit */
+ NULL, /* ^graph */
+ NULL, /* ^print */
+ NULL, /* ^punct */
+ string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
+ string_PXwd, /* ^word */
+ NULL /* ^xdigit */
+};
+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
+#endif
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+/* The texts of compile-time error messages. These are "char *" because they
+are passed to the outside world. Do not ever re-use any error number, because
+they are documented. Always add a new error instead. Messages marked DEAD below
+are no longer used. This used to be a table of strings, but in order to reduce
+the number of relocations needed when a shared library is loaded dynamically,
+it is now one long string. We cannot use a table of offsets, because the
+lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
+simply count through to the one we want - this isn't a performance issue
+because these strings are used only when there is a compilation error.
+
+Each substring ends with \0 to insert a null character. This includes the final
+substring, so that the whole string ends with \0\0, which can be detected when
+counting through. */
+
+static const char error_texts[] =
+ "no error\0"
+ "\\ at end of pattern\0"
+ "\\c at end of pattern\0"
+ "unrecognized character follows \\\0"
+ "numbers out of order in {} quantifier\0"
+ /* 5 */
+ "number too big in {} quantifier\0"
+ "missing terminating ] for character class\0"
+ "invalid escape sequence in character class\0"
+ "range out of order in character class\0"
+ "nothing to repeat\0"
+ /* 10 */
+ "operand of unlimited repeat could match the empty string\0" /** DEAD **/
+ "internal error: unexpected repeat\0"
+ "unrecognized character after (? or (?-\0"
+ "POSIX named classes are supported only within a class\0"
+ "missing )\0"
+ /* 15 */
+ "reference to non-existent subpattern\0"
+ "erroffset passed as NULL\0"
+ "unknown option bit(s) set\0"
+ "missing ) after comment\0"
+ "parentheses nested too deeply\0" /** DEAD **/
+ /* 20 */
+ "regular expression is too large\0"
+ "failed to get memory\0"
+ "unmatched parentheses\0"
+ "internal error: code overflow\0"
+ "unrecognized character after (?<\0"
+ /* 25 */
+ "lookbehind assertion is not fixed length\0"
+ "malformed number or name after (?(\0"
+ "conditional group contains more than two branches\0"
+ "assertion expected after (?(\0"
+ "(?R or (?[+-]digits must be followed by )\0"
+ /* 30 */
+ "unknown POSIX class name\0"
+ "POSIX collating elements are not supported\0"
+ "this version of PCRE is compiled without UTF support\0"
+ "spare error\0" /** DEAD **/
+ "character value in \\x{...} sequence is too large\0"
+ /* 35 */
+ "invalid condition (?(0)\0"
+ "\\C not allowed in lookbehind assertion\0"
+ "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
+ "number after (?C is > 255\0"
+ "closing ) for (?C expected\0"
+ /* 40 */
+ "recursive call could loop indefinitely\0"
+ "unrecognized character after (?P\0"
+ "syntax error in subpattern name (missing terminator)\0"
+ "two named subpatterns have the same name\0"
+ "invalid UTF-8 string\0"
+ /* 45 */
+ "support for \\P, \\p, and \\X has not been compiled\0"
+ "malformed \\P or \\p sequence\0"
+ "unknown property name after \\P or \\p\0"
+ "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
+ "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
+ /* 50 */
+ "repeated subpattern is too long\0" /** DEAD **/
+ "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
+ "internal error: overran compiling workspace\0"
+ "internal error: previously-checked referenced subpattern not found\0"
+ "DEFINE group contains more than one branch\0"
+ /* 55 */
+ "repeating a DEFINE group is not allowed\0" /** DEAD **/
+ "inconsistent NEWLINE options\0"
+ "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
+ "a numbered reference must not be zero\0"
+ "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
+ /* 60 */
+ "(*VERB) not recognized\0"
+ "number is too big\0"
+ "subpattern name expected\0"
+ "digit expected after (?+\0"
+ "] is an invalid data character in JavaScript compatibility mode\0"
+ /* 65 */
+ "different names for subpatterns of the same number are not allowed\0"
+ "(*MARK) must have an argument\0"
+ "this version of PCRE is not compiled with Unicode property support\0"
+ "\\c must be followed by an ASCII character\0"
+ "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
+ /* 70 */
+ "internal error: unknown opcode in find_fixedlength()\0"
+ "\\N is not supported in a class\0"
+ "too many forward references\0"
+ "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
+ "invalid UTF-16 string\0"
+ ;
+
+/* Table to identify digits and hex digits. This is used when compiling
+patterns. Note that the tables in chartables are dependent on the locale, and
+may mark arbitrary characters as digits - but the PCRE compiling code expects
+to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
+a private table here. It costs 256 bytes, but it is a lot faster than doing
+character value tests (at least in some simple cases I timed), and in some
+applications one wants PCRE to compile efficiently as well as match
+efficiently.
+
+For convenience, we use the same bit definitions as in chartables:
+
+ 0x04 decimal digit
+ 0x08 hexadecimal digit
+
+Then we can use ctype_digit and ctype_xdigit in the code. */
+
+/* Using a simple comparison for decimal numbers rather than a memory read
+is much faster, and the resulting code is simpler (the compiler turns it
+into a subtraction and unsigned comparison). */
+
+#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
+
+#ifndef EBCDIC
+
+/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
+UTF-8 mode. */
+
+static const pcre_uint8 digitab[] =
+ {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
+ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+#else
+
+/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
+
+static const pcre_uint8 digitab[] =
+ {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
+ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
+
+static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
+ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
+ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
+ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
+ 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
+ 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
+ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
+ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
+ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
+ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
+#endif
+
+
+/* Definition to allow mutual recursion */
+
+static BOOL
+ compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int,
+ int *, int *, branch_chain *, compile_data *, int *);
+
+
+
+/*************************************************
+* Find an error text *
+*************************************************/
+
+/* The error texts are now all in one long string, to save on relocations. As
+some of the text is of unknown length, we can't use a table of offsets.
+Instead, just count through the strings. This is not a performance issue
+because it happens only when there has been a compilation error.
+
+Argument: the error number
+Returns: pointer to the error string
+*/
+
+static const char *
+find_error_text(int n)
+{
+const char *s = error_texts;
+for (; n > 0; n--)
+ {
+ while (*s++ != 0) {};
+ if (*s == 0) return "Error text not found (please report)";
+ }
+return s;
+}
+
+
+/*************************************************
+* Expand the workspace *
+*************************************************/
+
+/* This function is called during the second compiling phase, if the number of
+forward references fills the existing workspace, which is originally a block on
+the stack. A larger block is obtained from malloc() unless the ultimate limit
+has been reached or the increase will be rather small.
+
+Argument: pointer to the compile data block
+Returns: 0 if all went well, else an error number
+*/
+
+static int
+expand_workspace(compile_data *cd)
+{
+pcre_uchar *newspace;
+int newsize = cd->workspace_size * 2;
+
+if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;
+if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
+ newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
+ return ERR72;
+
+newspace = (PUBL(malloc))(IN_UCHARS(newsize));
+if (newspace == NULL) return ERR21;
+memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
+cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+cd->start_workspace = newspace;
+cd->workspace_size = newsize;
+return 0;
+}
+
+
+
+/*************************************************
+* Check for counted repeat *
+*************************************************/
+
+/* This function is called when a '{' is encountered in a place where it might
+start a quantifier. It looks ahead to see if it really is a quantifier or not.
+It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
+where the ddds are digits.
+
+Arguments:
+ p pointer to the first char after '{'
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_counted_repeat(const pcre_uchar *p)
+{
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (*p++ != CHAR_COMMA) return FALSE;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+
+return (*p == CHAR_RIGHT_CURLY_BRACKET);
+}
+
+
+
+/*************************************************
+* Handle escapes *
+*************************************************/
+
+/* This function is called when a \ has been encountered. It either returns a
+positive value for a simple escape such as \n, or a negative value which
+encodes one of the more complicated things such as \d. A backreference to group
+n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When
+UTF-8 is enabled, a positive value greater than 255 may be returned. On entry,
+ptr is pointing at the \. On exit, it is on the final character of the escape
+sequence.
+
+Arguments:
+ ptrptr points to the pattern position pointer
+ errorcodeptr points to the errorcode variable
+ bracount number of previous extracting brackets
+ options the options bits
+ isclass TRUE if inside a character class
+
+Returns: zero or positive => a data character
+ negative => a special escape sequence
+ on error, errorcodeptr is set
+*/
+
+static int
+check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount,
+ int options, BOOL isclass)
+{
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+const pcre_uchar *ptr = *ptrptr + 1;
+pcre_int32 c;
+int i;
+
+GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
+ptr--; /* Set pointer back to the last byte */
+
+/* If backslash is at the end of the pattern, it's an error. */
+
+if (c == 0) *errorcodeptr = ERR1;
+
+/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
+in a table. A non-zero result is something that can be returned immediately.
+Otherwise further processing may be required. */
+
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+/* Not alphanumeric */
+else if (c < CHAR_0 || c > CHAR_z) {}
+else if ((i = escapes[c - CHAR_0]) != 0) c = i;
+
+#else /* EBCDIC coding */
+/* Not alphanumeric */
+else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {}
+else if ((i = escapes[c - 0x48]) != 0) c = i;
+#endif
+
+/* Escapes that need further processing, or are illegal. */
+
+else
+ {
+ const pcre_uchar *oldptr;
+ BOOL braced, negated;
+
+ switch (c)
+ {
+ /* A number of Perl escapes are not handled by PCRE. We give an explicit
+ error. */
+
+ case CHAR_l:
+ case CHAR_L:
+ *errorcodeptr = ERR37;
+ break;
+
+ case CHAR_u:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \u must be followed by four hexadecimal numbers.
+ Otherwise it is a lowercase u letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0
+ && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0
+ && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 4; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ }
+ }
+ else
+ *errorcodeptr = ERR37;
+ break;
+
+ case CHAR_U:
+ /* In JavaScript, \U is an uppercase U letter. */
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37;
+ break;
+
+ /* In a character class, \g is just a literal "g". Outside a character
+ class, \g must be followed by one of a number of specific things:
+
+ (1) A number, either plain or braced. If positive, it is an absolute
+ backreference. If negative, it is a relative backreference. This is a Perl
+ 5.10 feature.
+
+ (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
+ is part of Perl's movement towards a unified syntax for back references. As
+ this is synonymous with \k{name}, we fudge it up by pretending it really
+ was \k.
+
+ (3) For Oniguruma compatibility we also support \g followed by a name or a
+ number either in angle brackets or in single quotes. However, these are
+ (possibly recursive) subroutine calls, _not_ backreferences. Just return
+ the -ESC_g code (cf \k). */
+
+ case CHAR_g:
+ if (isclass) break;
+ if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
+ {
+ c = -ESC_g;
+ break;
+ }
+
+ /* Handle the Perl-compatible cases */
+
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+ {
+ const pcre_uchar *p;
+ for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
+ if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
+ if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ c = -ESC_k;
+ break;
+ }
+ braced = TRUE;
+ ptr++;
+ }
+ else braced = FALSE;
+
+ if (ptr[1] == CHAR_MINUS)
+ {
+ negated = TRUE;
+ ptr++;
+ }
+ else negated = FALSE;
+
+ /* The integer range is limited by the machine's int representation. */
+ c = 0;
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
+ c = c * 10 + *(++ptr) - CHAR_0;
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
+ {
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
+ *errorcodeptr = ERR61;
+ break;
+ }
+
+ if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+
+ if (c == 0)
+ {
+ *errorcodeptr = ERR58;
+ break;
+ }
+
+ if (negated)
+ {
+ if (c > bracount)
+ {
+ *errorcodeptr = ERR15;
+ break;
+ }
+ c = bracount - (c - 1);
+ }
+
+ c = -(ESC_REF + c);
+ break;
+
+ /* The handling of escape sequences consisting of a string of digits
+ starting with one that is not zero is not straightforward. By experiment,
+ the way Perl works seems to be as follows:
+
+ Outside a character class, the digits are read as a decimal number. If the
+ number is less than 10, or if there are that many previous extracting
+ left brackets, then it is a back reference. Otherwise, up to three octal
+ digits are read to form an escaped byte. Thus \123 is likely to be octal
+ 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
+ value is greater than 377, the least significant 8 bits are taken. Inside a
+ character class, \ followed by a digit is always an octal number. */
+
+ case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
+ case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+
+ if (!isclass)
+ {
+ oldptr = ptr;
+ /* The integer range is limited by the machine's int representation. */
+ c -= CHAR_0;
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
+ c = c * 10 + *(++ptr) - CHAR_0;
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
+ {
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
+ *errorcodeptr = ERR61;
+ break;
+ }
+ if (c < 10 || c <= bracount)
+ {
+ c = -(ESC_REF + c);
+ break;
+ }
+ ptr = oldptr; /* Put the pointer back and fall through */
+ }
+
+ /* Handle an octal number following \. If the first digit is 8 or 9, Perl
+ generates a binary zero byte and treats the digit as a following literal.
+ Thus we have to pull back the pointer by one. */
+
+ if ((c = *ptr) >= CHAR_8)
+ {
+ ptr--;
+ c = 0;
+ break;
+ }
+
+ /* \0 always starts an octal number, but we may drop through to here with a
+ larger first octal digit. The original code used just to take the least
+ significant 8 bits of octal numbers (I think this is what early Perls used
+ to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
+ but no more than 3 octal digits. */
+
+ case CHAR_0:
+ c -= CHAR_0;
+ while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
+ c = c * 8 + *(++ptr) - CHAR_0;
+#ifdef COMPILE_PCRE8
+ if (!utf && c > 0xff) *errorcodeptr = ERR51;
+#endif
+ break;
+
+ /* \x is complicated. \x{ddd} is a character number which can be greater
+ than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
+ If not, { is treated as a data character. */
+
+ case CHAR_x:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \x must be followed by two hexadecimal numbers.
+ Otherwise it is a lowercase x letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 2; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ }
+ break;
+ }
+
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+ {
+ const pcre_uchar *pt = ptr + 2;
+
+ c = 0;
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
+ {
+ register int cc = *pt++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+
+#ifdef COMPILE_PCRE8
+ if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; }
+#else
+#ifdef COMPILE_PCRE16
+ if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; }
+#endif
+#endif
+ }
+
+ if (c < 0)
+ {
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
+ *errorcodeptr = ERR34;
+ }
+
+ if (*pt == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ ptr = pt;
+ break;
+ }
+
+ /* If the sequence of hex digits does not end with '}', then we don't
+ recognize this construct; fall through to the normal \x handling. */
+ }
+
+ /* Read just a single-byte hex-defined char */
+
+ c = 0;
+ while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
+ {
+ int cc; /* Some compilers don't like */
+ cc = *(++ptr); /* ++ in initializers */
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ break;
+
+ /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
+ An error is given if the byte following \c is not an ASCII character. This
+ coding is ASCII-specific, but then the whole concept of \cx is
+ ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
+
+ case CHAR_c:
+ c = *(++ptr);
+ if (c == 0)
+ {
+ *errorcodeptr = ERR2;
+ break;
+ }
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (c > 127) /* Excludes all non-ASCII in either mode */
+ {
+ *errorcodeptr = ERR68;
+ break;
+ }
+ if (c >= CHAR_a && c <= CHAR_z) c -= 32;
+ c ^= 0x40;
+#else /* EBCDIC coding */
+ if (c >= CHAR_a && c <= CHAR_z) c += 64;
+ c ^= 0xC0;
+#endif
+ break;
+
+ /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
+ other alphanumeric following \ is an error if PCRE_EXTRA was set;
+ otherwise, for Perl compatibility, it is a literal. This code looks a bit
+ odd, but there used to be some cases other than the default, and there may
+ be again in future, so I haven't "optimized" it. */
+
+ default:
+ if ((options & PCRE_EXTRA) != 0) switch(c)
+ {
+ default:
+ *errorcodeptr = ERR3;
+ break;
+ }
+ break;
+ }
+ }
+
+/* Perl supports \N{name} for character names, as well as plain \N for "not
+newline". PCRE does not support \N{name}. However, it does support
+quantification such as \N{2,3}. */
+
+if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
+ !is_counted_repeat(ptr+2))
+ *errorcodeptr = ERR37;
+
+/* If PCRE_UCP is set, we change the values for \d etc. */
+
+if ((options & PCRE_UCP) != 0 && c <= -ESC_D && c >= -ESC_w)
+ c -= (ESC_DU - ESC_D);
+
+/* Set the pointer to the final character before returning. */
+
+*ptrptr = ptr;
+return c;
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* Handle \P and \p *
+*************************************************/
+
+/* This function is called after \P or \p has been encountered, provided that
+PCRE is compiled with support for Unicode properties. On entry, ptrptr is
+pointing at the P or p. On exit, it is pointing at the final character of the
+escape sequence.
+
+Argument:
+ ptrptr points to the pattern position pointer
+ negptr points to a boolean that is set TRUE for negation else FALSE
+ dptr points to an int that is set to the detailed property value
+ errorcodeptr points to the error code variable
+
+Returns: type value from ucp_type_table, or -1 for an invalid type
+*/
+
+static int
+get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
+{
+int c, i, bot, top;
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar name[32];
+
+c = *(++ptr);
+if (c == 0) goto ERROR_RETURN;
+
+*negptr = FALSE;
+
+/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
+negation. */
+
+if (c == CHAR_LEFT_CURLY_BRACKET)
+ {
+ if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ *negptr = TRUE;
+ ptr++;
+ }
+ for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++)
+ {
+ c = *(++ptr);
+ if (c == 0) goto ERROR_RETURN;
+ if (c == CHAR_RIGHT_CURLY_BRACKET) break;
+ name[i] = c;
+ }
+ if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
+ name[i] = 0;
+ }
+
+/* Otherwise there is just one following character */
+
+else
+ {
+ name[0] = c;
+ name[1] = 0;
+ }
+
+*ptrptr = ptr;
+
+/* Search for a recognized property name using binary chop */
+
+bot = 0;
+top = PRIV(utt_size);
+
+while (bot < top)
+ {
+ i = (bot + top) >> 1;
+ c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
+ if (c == 0)
+ {
+ *dptr = PRIV(utt)[i].value;
+ return PRIV(utt)[i].type;
+ }
+ if (c > 0) bot = i + 1; else top = i;
+ }
+
+*errorcodeptr = ERR47;
+*ptrptr = ptr;
+return -1;
+
+ERROR_RETURN:
+*errorcodeptr = ERR46;
+*ptrptr = ptr;
+return -1;
+}
+#endif
+
+
+
+
+/*************************************************
+* Read repeat counts *
+*************************************************/
+
+/* Read an item of the form {n,m} and return the values. This is called only
+after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
+so the syntax is guaranteed to be correct, but we need to check the values.
+
+Arguments:
+ p pointer to first char after '{'
+ minp pointer to int for min
+ maxp pointer to int for max
+ returned as -1 if no max
+ errorcodeptr points to error code variable
+
+Returns: pointer to '}' on success;
+ current ptr on error, with errorcodeptr set non-zero
+*/
+
+static const pcre_uchar *
+read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
+{
+int min = 0;
+int max = -1;
+
+/* Read the minimum value and do a paranoid check: a negative value indicates
+an integer overflow. */
+
+while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0;
+if (min < 0 || min > 65535)
+ {
+ *errorcodeptr = ERR5;
+ return p;
+ }
+
+/* Read the maximum value if there is one, and again do a paranoid on its size.
+Also, max must not be less than min. */
+
+if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
+ {
+ if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ max = 0;
+ while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0;
+ if (max < 0 || max > 65535)
+ {
+ *errorcodeptr = ERR5;
+ return p;
+ }
+ if (max < min)
+ {
+ *errorcodeptr = ERR4;
+ return p;
+ }
+ }
+ }
+
+/* Fill in the required variables, and pass back the pointer to the terminating
+'}'. */
+
+*minp = min;
+*maxp = max;
+return p;
+}
+
+
+
+/*************************************************
+* Subroutine for finding forward reference *
+*************************************************/
+
+/* This recursive function is called only from find_parens() below. The
+top-level call starts at the beginning of the pattern. All other calls must
+start at a parenthesis. It scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. Recursion is used to keep
+track of subpatterns that reset the capturing group numbers - the (?| feature.
+
+This function was originally called only from the second pass, in which we know
+that if (?< or (?' or (?P< is encountered, the name will be correctly
+terminated because that is checked in the first pass. There is now one call to
+this function in the first pass, to check for a recursive back reference by
+name (so that we can make the whole group atomic). In this case, we need check
+only up to the current position in the pattern, and that is still OK because
+and previous occurrences will have been checked. To make this work, the test
+for "end of pattern" is a check against cd->end_pattern in the main loop,
+instead of looking for a binary zero. This means that the special first-pass
+call can adjust cd->end_pattern temporarily. (Checks for binary zero while
+processing items within the loop are OK, because afterwards the main loop will
+terminate.)
+
+Arguments:
+ ptrptr address of the current character pointer (updated)
+ cd compile background data
+ name name to seek, or NULL if seeking a numbered subpattern
+ lorn name length, or subpattern number if name is NULL
+ xmode TRUE if we are in /x mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
+ count pointer to the current capturing subpattern number (updated)
+
+Returns: the number of the named subpattern, or -1 if not found
+*/
+
+static int
+find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
+ BOOL xmode, BOOL utf, int *count)
+{
+pcre_uchar *ptr = *ptrptr;
+int start_count = *count;
+int hwm_count = start_count;
+BOOL dup_parens = FALSE;
+
+/* If the first character is a parenthesis, check on the type of group we are
+dealing with. The very first call may not start with a parenthesis. */
+
+if (ptr[0] == CHAR_LEFT_PARENTHESIS)
+ {
+ /* Handle specials such as (*SKIP) or (*UTF8) etc. */
+
+ if (ptr[1] == CHAR_ASTERISK) ptr += 2;
+
+ /* Handle a normal, unnamed capturing parenthesis. */
+
+ else if (ptr[1] != CHAR_QUESTION_MARK)
+ {
+ *count += 1;
+ if (name == NULL && *count == lorn) return *count;
+ ptr++;
+ }
+
+ /* All cases now have (? at the start. Remember when we are in a group
+ where the parenthesis numbers are duplicated. */
+
+ else if (ptr[2] == CHAR_VERTICAL_LINE)
+ {
+ ptr += 3;
+ dup_parens = TRUE;
+ }
+
+ /* Handle comments; all characters are allowed until a ket is reached. */
+
+ else if (ptr[2] == CHAR_NUMBER_SIGN)
+ {
+ for (ptr += 3; *ptr != 0; ptr++) if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
+ goto FAIL_EXIT;
+ }
+
+ /* Handle a condition. If it is an assertion, just carry on so that it
+ is processed as normal. If not, skip to the closing parenthesis of the
+ condition (there can't be any nested parens). */
+
+ else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
+ {
+ ptr += 2;
+ if (ptr[1] != CHAR_QUESTION_MARK)
+ {
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ if (*ptr != 0) ptr++;
+ }
+ }
+
+ /* Start with (? but not a condition. */
+
+ else
+ {
+ ptr += 2;
+ if (*ptr == CHAR_P) ptr++; /* Allow optional P */
+
+ /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
+
+ if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
+ ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
+ {
+ int term;
+ const pcre_uchar *thisname;
+ *count += 1;
+ if (name == NULL && *count == lorn) return *count;
+ term = *ptr++;
+ if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
+ thisname = ptr;
+ while (*ptr != term) ptr++;
+ if (name != NULL && lorn == ptr - thisname &&
+ STRNCMP_UC_UC(name, thisname, lorn) == 0)
+ return *count;
+ term++;
+ }
+ }
+ }
+
+/* Past any initial parenthesis handling, scan for parentheses or vertical
+bars. Stop if we get to cd->end_pattern. Note that this is important for the
+first-pass call when this value is temporarily adjusted to stop at the current
+position. So DO NOT change this to a test for binary zero. */
+
+for (; ptr < cd->end_pattern; ptr++)
+ {
+ /* Skip over backslashed characters and also entire \Q...\E */
+
+ if (*ptr == CHAR_BACKSLASH)
+ {
+ if (*(++ptr) == 0) goto FAIL_EXIT;
+ if (*ptr == CHAR_Q) for (;;)
+ {
+ while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+ if (*ptr == 0) goto FAIL_EXIT;
+ if (*(++ptr) == CHAR_E) break;
+ }
+ continue;
+ }
+
+ /* Skip over character classes; this logic must be similar to the way they
+ are handled for real. If the first character is '^', skip it. Also, if the
+ first few characters (either before or after ^) are \Q\E or \E we skip them
+ too. This makes for compatibility with Perl. Note the use of STR macros to
+ encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
+
+ if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
+ {
+ BOOL negate_class = FALSE;
+ for (;;)
+ {
+ if (ptr[1] == CHAR_BACKSLASH)
+ {
+ if (ptr[2] == CHAR_E)
+ ptr+= 2;
+ else if (STRNCMP_UC_C8(ptr + 2,
+ STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ ptr += 4;
+ else
+ break;
+ }
+ else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ negate_class = TRUE;
+ ptr++;
+ }
+ else break;
+ }
+
+ /* If the next character is ']', it is a data character that must be
+ skipped, except in JavaScript compatibility mode. */
+
+ if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
+ (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ ptr++;
+
+ while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
+ {
+ if (*ptr == 0) return -1;
+ if (*ptr == CHAR_BACKSLASH)
+ {
+ if (*(++ptr) == 0) goto FAIL_EXIT;
+ if (*ptr == CHAR_Q) for (;;)
+ {
+ while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+ if (*ptr == 0) goto FAIL_EXIT;
+ if (*(++ptr) == CHAR_E) break;
+ }
+ continue;
+ }
+ }
+ continue;
+ }
+
+ /* Skip comments in /x mode */
+
+ if (xmode && *ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ if (*ptr == 0) goto FAIL_EXIT;
+ continue;
+ }
+
+ /* Check for the special metacharacters */
+
+ if (*ptr == CHAR_LEFT_PARENTHESIS)
+ {
+ int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
+ if (rc > 0) return rc;
+ if (*ptr == 0) goto FAIL_EXIT;
+ }
+
+ else if (*ptr == CHAR_RIGHT_PARENTHESIS)
+ {
+ if (dup_parens && *count < hwm_count) *count = hwm_count;
+ goto FAIL_EXIT;
+ }
+
+ else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
+ {
+ if (*count > hwm_count) hwm_count = *count;
+ *count = start_count;
+ }
+ }
+
+FAIL_EXIT:
+*ptrptr = ptr;
+return -1;
+}
+
+
+
+
+/*************************************************
+* Find forward referenced subpattern *
+*************************************************/
+
+/* This function scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. This is used for forward
+references to subpatterns. We used to be able to start this scan from the
+current compiling point, using the current count value from cd->bracount, and
+do it all in a single loop, but the addition of the possibility of duplicate
+subpattern numbers means that we have to scan from the very start, in order to
+take account of such duplicates, and to use a recursive function to keep track
+of the different types of group.
+
+Arguments:
+ cd compile background data
+ name name to seek, or NULL if seeking a numbered subpattern
+ lorn name length, or subpattern number if name is NULL
+ xmode TRUE if we are in /x mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
+
+Returns: the number of the found subpattern, or -1 if not found
+*/
+
+static int
+find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
+ BOOL utf)
+{
+pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
+int count = 0;
+int rc;
+
+/* If the pattern does not start with an opening parenthesis, the first call
+to find_parens_sub() will scan right to the end (if necessary). However, if it
+does start with a parenthesis, find_parens_sub() will return when it hits the
+matching closing parens. That is why we have to have a loop. */
+
+for (;;)
+ {
+ rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
+ if (rc > 0 || *ptr++ == 0) break;
+ }
+
+return rc;
+}
+
+
+
+
+/*************************************************
+* Find first significant op code *
+*************************************************/
+
+/* This is called by several functions that scan a compiled expression looking
+for a fixed first character, or an anchoring op code etc. It skips over things
+that do not influence this. For some calls, it makes sense to skip negative
+forward and all backward assertions, and also the \b assertion; for others it
+does not.
+
+Arguments:
+ code pointer to the start of the group
+ skipassert TRUE if certain assertions are to be skipped
+
+Returns: pointer to the first significant opcode
+*/
+
+static const pcre_uchar*
+first_significant_code(const pcre_uchar *code, BOOL skipassert)
+{
+for (;;)
+ {
+ switch ((int)*code)
+ {
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ if (!skipassert) return code;
+ do code += GET(code, 1); while (*code == OP_ALT);
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ if (!skipassert) return code;
+ /* Fall through */
+
+ case OP_CALLOUT:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ default:
+ return code;
+ }
+ }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+* Find the fixed length of a branch *
+*************************************************/
+
+/* Scan a branch and compute the fixed length of subject that will match it,
+if the length is fixed. This is needed for dealing with backward assertions.
+In UTF8 mode, the result is in characters rather than bytes. The branch is
+temporarily terminated with OP_END when this function is called.
+
+This function is called when a backward assertion is encountered, so that if it
+fails, the error message can point to the correct place in the pattern.
+However, we cannot do this when the assertion contains subroutine calls,
+because they can be forward references. We solve this by remembering this case
+and doing the check at the end; a flag specifies which mode we are running in.
+
+Arguments:
+ code points to the start of the pattern (the bracket)
+ utf TRUE in UTF-8 / UTF-16 mode
+ atend TRUE if called when the pattern is complete
+ cd the "compile data" structure
+
+Returns: the fixed length,
+ or -1 if there is no fixed length,
+ or -2 if \C was encountered (in UTF-8 mode only)
+ or -3 if an OP_RECURSE item was encountered and atend is FALSE
+ or -4 if an unknown opcode was encountered (internal error)
+*/
+
+static int
+find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
+{
+int length = -1;
+
+register int branchlength = 0;
+register pcre_uchar *cc = code + 1 + LINK_SIZE;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+ {
+ int d;
+ pcre_uchar *ce, *cs;
+ register int op = *cc;
+
+ switch (op)
+ {
+ /* We only need to continue for OP_CBRA (normal capturing bracket) and
+ OP_BRA (normal non-capturing bracket) because the other variants of these
+ opcodes are all concerned with unlimited repeated groups, which of course
+ are not of fixed length. */
+
+ case OP_CBRA:
+ case OP_BRA:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
+ if (d < 0) return d;
+ branchlength += d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Reached end of a branch; if it's a ket it is the end of a nested call.
+ If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
+ an ALT. If it is END it's the end of the outer call. All can be handled by
+ the same code. Note that we must not include the OP_KETRxxx opcodes here,
+ because they all imply an unlimited repeat. */
+
+ case OP_ALT:
+ case OP_KET:
+ case OP_END:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ if (length < 0) length = branchlength;
+ else if (length != branchlength) return -1;
+ if (*cc != OP_ALT) return length;
+ cc += 1 + LINK_SIZE;
+ branchlength = 0;
+ break;
+
+ /* A true recursion implies not fixed length, but a subroutine call may
+ be OK. If the subroutine is a forward reference, we can't deal with
+ it until the end of the pattern, so return -3. */
+
+ case OP_RECURSE:
+ if (!atend) return -3;
+ cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
+ do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
+ if (cc > cs && cc < ce) return -1; /* Recursion */
+ d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
+ if (d < 0) return d;
+ branchlength += d;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Skip over assertive subpatterns */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Skip over things that don't match chars */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += cc[1] + PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_CALLOUT:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_CREF:
+ case OP_DEF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_FAIL:
+ case OP_NCREF:
+ case OP_NRREF:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_PRUNE:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_WORD_BOUNDARY:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Handle literal characters */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ branchlength++;
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ /* Handle exact repetitions. The count is already in characters, but we
+ need to skip over a multibyte character in UTF8 mode. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEEXACT:
+ branchlength += GET2(cc,1);
+ if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+
+ /* Handle single-char matchers */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ cc += 2;
+ /* Fall through */
+
+ case OP_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ branchlength++;
+ cc++;
+ break;
+
+ /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
+ otherwise \C is coded as OP_ALLANY. */
+
+ case OP_ANYBYTE:
+ return -2;
+
+ /* Check a class for variable quantification */
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
+ /* Fall through */
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ cc += PRIV(OP_lengths)[OP_CLASS];
+
+ switch (*cc)
+ {
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ return -1;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
+ branchlength += GET2(cc,1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ branchlength++;
+ }
+ break;
+
+ /* Anything else is variable length */
+
+ case OP_ANYNL:
+ case OP_BRAMINZERO:
+ case OP_BRAPOS:
+ case OP_BRAPOSZERO:
+ case OP_BRAZERO:
+ case OP_CBRAPOS:
+ case OP_EXTUNI:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_REF:
+ case OP_REFI:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ case OP_SCOND:
+ case OP_SKIPZERO:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEQUERY:
+ case OP_TYPESTAR:
+ case OP_TYPEUPTO:
+ case OP_UPTO:
+ case OP_UPTOI:
+ return -1;
+
+ /* Catch unrecognized opcodes so that when new ones are added they
+ are not forgotten, as has happened in the past. */
+
+ default:
+ return -4;
+ }
+ }
+/* Control never gets here */
+}
+
+
+
+
+/*************************************************
+* Scan compiled regex for specific bracket *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds a
+capturing bracket with the given number, or, if the number is negative, an
+instance of OP_REVERSE for a lookbehind. The function is global in the C sense
+so that it can be called from pcre_study() when finding the minimum matching
+length.
+
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF-8 / UTF-16 mode
+ number the required bracket number or negative to find a lookbehind
+
+Returns: pointer to the opcode for the bracket, or NULL if not found
+*/
+
+const pcre_uchar *
+PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number)
+{
+for (;;)
+ {
+ register int c = *code;
+
+ if (c == OP_END) return NULL;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit
+ map. This includes negated single high-valued characters. The length in
+ the table is zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+
+ /* Handle recursion */
+
+ else if (c == OP_REVERSE)
+ {
+ if (number < 0) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Handle capturing bracket */
+
+ else if (c == OP_CBRA || c == OP_SCBRA ||
+ c == OP_CBRAPOS || c == OP_SCBRAPOS)
+ {
+ int n = GET2(code, 1+LINK_SIZE);
+ if (n == number) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
+ must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 mode, opcodes that are followed by a character may be followed by
+ a multi-byte character. The length in the table is a minimum, so we have to
+ arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+ }
+}
+
+
+
+/*************************************************
+* Scan compiled regex for recursion reference *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds an
+instance of OP_RECURSE.
+
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF-8 / UTF-16 mode
+
+Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
+*/
+
+static const pcre_uchar *
+find_recurse(const pcre_uchar *code, BOOL utf)
+{
+for (;;)
+ {
+ register int c = *code;
+ if (c == OP_END) return NULL;
+ if (c == OP_RECURSE) return code;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit
+ map. This includes negated single high-valued characters. The length in
+ the table is zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
+ must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 mode, opcodes that are followed by a character may be followed
+ by a multi-byte character. The length in the table is a minimum, so we have
+ to arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+ }
+}
+
+
+
+/*************************************************
+* Scan compiled branch for non-emptiness *
+*************************************************/
+
+/* This function scans through a branch of a compiled pattern to see whether it
+can match the empty string or not. It is called from could_be_empty()
+below and from compile_branch() when checking for an unlimited repeat of a
+group that can match nothing. Note that first_significant_code() skips over
+backward and negative forward assertions when its final argument is TRUE. If we
+hit an unclosed bracket, we return "empty" - this means we've struck an inner
+bracket whose current branch will already have been scanned.
+
+Arguments:
+ code points to start of search
+ endcode points to where to stop
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd contains pointers to tables etc.
+
+Returns: TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
+ BOOL utf, compile_data *cd)
+{
+register int c;
+for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
+ code < endcode;
+ code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
+ {
+ const pcre_uchar *ccode;
+
+ c = *code;
+
+ /* Skip over forward assertions; the other assertions are skipped by
+ first_significant_code() with a TRUE final argument. */
+
+ if (c == OP_ASSERT)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* For a recursion/subroutine call, if its end has been reached, which
+ implies a backward reference subroutine call, we can scan it. If it's a
+ forward reference subroutine call, we can't. To detect forward reference
+ we have to scan up the list that is kept in the workspace. This function is
+ called only when doing the real compile, not during the pre-compile that
+ measures the size of the compiled pattern. */
+
+ if (c == OP_RECURSE)
+ {
+ const pcre_uchar *scode;
+ BOOL empty_branch;
+
+ /* Test for forward reference */
+
+ for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
+ if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE;
+
+ /* Not a forward reference, test for completed backward reference */
+
+ empty_branch = FALSE;
+ scode = cd->start_code + GET(code, 1);
+ if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+
+ /* Completed backwards reference */
+
+ do
+ {
+ if (could_be_empty_branch(scode, endcode, utf, cd))
+ {
+ empty_branch = TRUE;
+ break;
+ }
+ scode += GET(scode, 1);
+ }
+ while (*scode == OP_ALT);
+
+ if (!empty_branch) return FALSE; /* All branches are non-empty */
+ continue;
+ }
+
+ /* Groups with zero repeats can of course be empty; skip them. */
+
+ if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
+ c == OP_BRAPOSZERO)
+ {
+ code += PRIV(OP_lengths)[c];
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* A nested group that is already marked as "could be empty" can just be
+ skipped. */
+
+ if (c == OP_SBRA || c == OP_SBRAPOS ||
+ c == OP_SCBRA || c == OP_SCBRAPOS)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* For other groups, scan the branches. */
+
+ if (c == OP_BRA || c == OP_BRAPOS ||
+ c == OP_CBRA || c == OP_CBRAPOS ||
+ c == OP_ONCE || c == OP_ONCE_NC ||
+ c == OP_COND)
+ {
+ BOOL empty_branch;
+ if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
+
+ /* If a conditional group has only one branch, there is a second, implied,
+ empty branch, so just skip over the conditional, because it could be empty.
+ Otherwise, scan the individual branches of the group. */
+
+ if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
+ code += GET(code, 1);
+ else
+ {
+ empty_branch = FALSE;
+ do
+ {
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
+ empty_branch = TRUE;
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ if (!empty_branch) return FALSE; /* All branches are non-empty */
+ }
+
+ c = *code;
+ continue;
+ }
+
+ /* Handle the other opcodes */
+
+ switch (c)
+ {
+ /* Check for quantifiers after a class. XCLASS is used for classes that
+ cannot be represented just by a bit map. This includes negated single
+ high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
+ actual length is stored in the compiled code, so we must update "code"
+ here. */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ ccode = code += GET(code, 1);
+ goto CHECK_CLASS_REPEAT;
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ ccode = code + PRIV(OP_lengths)[OP_CLASS];
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ CHECK_CLASS_REPEAT:
+#endif
+
+ switch (*ccode)
+ {
+ case OP_CRSTAR: /* These could be empty; continue */
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ break;
+
+ default: /* Non-repeat => class must match */
+ case OP_CRPLUS: /* These repeats aren't empty */
+ case OP_CRMINPLUS:
+ return FALSE;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
+ break;
+ }
+ break;
+
+ /* Opcodes that must match a character */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ case OP_EXTUNI:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_EXACT:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ case OP_NOTEXACT:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEEXACT:
+ return FALSE;
+
+ /* These are going to continue, as they may be empty, but we have to
+ fudge the length for the \p and \P cases. */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ /* Same for these */
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ /* End of branch */
+
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_ALT:
+ return TRUE;
+
+ /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
+ MINUPTO, and POSUPTO may be followed by a multibyte character */
+
+#ifdef SUPPORT_UTF
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
+ break;
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
+ break;
+#endif
+
+ /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
+ string. */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+
+ /* None of the remaining opcodes are required to match a character. */
+
+ default:
+ break;
+ }
+ }
+
+return TRUE;
+}
+
+
+
+/*************************************************
+* Scan compiled regex for non-emptiness *
+*************************************************/
+
+/* This function is called to check for left recursive calls. We want to check
+the current branch of the current pattern to see if it could match the empty
+string. If it could, we must look outwards for branches at other levels,
+stopping when we pass beyond the bracket which is the subject of the recursion.
+This function is called only during the real compile, not during the
+pre-compile.
+
+Arguments:
+ code points to start of the recursion
+ endcode points to where to stop (current RECURSE item)
+ bcptr points to the chain of current (unclosed) branch starts
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd pointers to tables etc
+
+Returns: TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
+ branch_chain *bcptr, BOOL utf, compile_data *cd)
+{
+while (bcptr != NULL && bcptr->current_branch >= code)
+ {
+ if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
+ return FALSE;
+ bcptr = bcptr->outer;
+ }
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for POSIX class syntax *
+*************************************************/
+
+/* This function is called when the sequence "[:" or "[." or "[=" is
+encountered in a character class. It checks whether this is followed by a
+sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
+reach an unescaped ']' without the special preceding character, return FALSE.
+
+Originally, this function only recognized a sequence of letters between the
+terminators, but it seems that Perl recognizes any sequence of characters,
+though of course unknown POSIX names are subsequently rejected. Perl gives an
+"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
+didn't consider this to be a POSIX class. Likewise for [:1234:].
+
+The problem in trying to be exactly like Perl is in the handling of escapes. We
+have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
+class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
+below handles the special case of \], but does not try to do any other escape
+processing. This makes it different from Perl for cases such as [:l\ower:]
+where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
+"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
+I think.
+
+A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
+It seems that the appearance of a nested POSIX class supersedes an apparent
+external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
+a digit.
+
+In Perl, unescaped square brackets may also appear as part of class names. For
+example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
+[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
+seem right at all. PCRE does not allow closing square brackets in POSIX class
+names.
+
+Arguments:
+ ptr pointer to the initial [
+ endptr where to return the end pointer
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr)
+{
+int terminator; /* Don't combine these lines; the Solaris cc */
+terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
+for (++ptr; *ptr != 0; ptr++)
+ {
+ if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ ptr++;
+ else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+ else
+ {
+ if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ {
+ *endptr = ptr;
+ return TRUE;
+ }
+ if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, endptr))
+ return FALSE;
+ }
+ }
+return FALSE;
+}
+
+
+
+
+/*************************************************
+* Check POSIX class name *
+*************************************************/
+
+/* This function is called to check the name given in a POSIX-style class entry
+such as [:alnum:].
+
+Arguments:
+ ptr points to the first letter
+ len the length of the name
+
+Returns: a value representing the name, or -1 if unknown
+*/
+
+static int
+check_posix_name(const pcre_uchar *ptr, int len)
+{
+const char *pn = posix_names;
+register int yield = 0;
+while (posix_name_lengths[yield] != 0)
+ {
+ if (len == posix_name_lengths[yield] &&
+ STRNCMP_UC_C8(ptr, pn, len) == 0) return yield;
+ pn += posix_name_lengths[yield] + 1;
+ yield++;
+ }
+return -1;
+}
+
+
+/*************************************************
+* Adjust OP_RECURSE items in repeated group *
+*************************************************/
+
+/* OP_RECURSE items contain an offset from the start of the regex to the group
+that is referenced. This means that groups can be replicated for fixed
+repetition simply by copying (because the recursion is allowed to refer to
+earlier groups that are outside the current group). However, when a group is
+optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
+inserted before it, after it has been compiled. This means that any OP_RECURSE
+items within it that refer to the group itself or any contained groups have to
+have their offsets adjusted. That one of the jobs of this function. Before it
+is called, the partially compiled regex must be temporarily terminated with
+OP_END.
+
+This function has been extended with the possibility of forward references for
+recursions and subroutine calls. It must also check the list of such references
+for the group we are dealing with. If it finds that one of the recursions in
+the current group is on this list, it adjusts the offset in the list, not the
+value in the reference (which is a group number).
+
+Arguments:
+ group points to the start of the group
+ adjust the amount by which the group is to be moved
+ utf TRUE in UTF-8 / UTF-16 mode
+ cd contains pointers to tables etc.
+ save_hwm the hwm forward reference pointer at the start of the group
+
+Returns: nothing
+*/
+
+static void
+adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
+ pcre_uchar *save_hwm)
+{
+pcre_uchar *ptr = group;
+
+while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
+ {
+ int offset;
+ pcre_uchar *hc;
+
+ /* See if this recursion is on the forward reference list. If so, adjust the
+ reference. */
+
+ for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
+ {
+ offset = GET(hc, 0);
+ if (cd->start_code + offset == ptr + 1)
+ {
+ PUT(hc, 0, offset + adjust);
+ break;
+ }
+ }
+
+ /* Otherwise, adjust the recursion offset if it's after the start of this
+ group. */
+
+ if (hc >= cd->hwm)
+ {
+ offset = GET(ptr, 1);
+ if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
+ }
+
+ ptr += 1 + LINK_SIZE;
+ }
+}
+
+
+
+/*************************************************
+* Insert an automatic callout point *
+*************************************************/
+
+/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
+callout points before each pattern item.
+
+Arguments:
+ code current code pointer
+ ptr current pattern pointer
+ cd pointers to tables etc
+
+Returns: new code pointer
+*/
+
+static pcre_uchar *
+auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
+{
+*code++ = OP_CALLOUT;
+*code++ = 255;
+PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
+PUT(code, LINK_SIZE, 0); /* Default length */
+return code + 2 * LINK_SIZE;
+}
+
+
+
+/*************************************************
+* Complete a callout item *
+*************************************************/
+
+/* A callout item contains the length of the next item in the pattern, which
+we can't fill in till after we have reached the relevant point. This is used
+for both automatic and manual callouts.
+
+Arguments:
+ previous_callout points to previous callout item
+ ptr current pattern pointer
+ cd pointers to tables etc
+
+Returns: nothing
+*/
+
+static void
+complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
+{
+int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
+PUT(previous_callout, 2 + LINK_SIZE, length);
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* Get othercase range *
+*************************************************/
+
+/* This function is passed the start and end of a class range, in UTF-8 mode
+with UCP support. It searches up the characters, looking for internal ranges of
+characters in the "other" case. Each call returns the next one, updating the
+start address.
+
+Arguments:
+ cptr points to starting character value; updated
+ d end value
+ ocptr where to put start of othercase range
+ odptr where to put end of othercase range
+
+Yield: TRUE when range returned; FALSE when no more
+*/
+
+static BOOL
+get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr,
+ unsigned int *odptr)
+{
+unsigned int c, othercase, next;
+
+for (c = *cptr; c <= d; c++)
+ { if ((othercase = UCD_OTHERCASE(c)) != c) break; }
+
+if (c > d) return FALSE;
+
+*ocptr = othercase;
+next = othercase + 1;
+
+for (++c; c <= d; c++)
+ {
+ if (UCD_OTHERCASE(c) != next) break;
+ next++;
+ }
+
+*odptr = next - 1;
+*cptr = c;
+
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check a character and a property *
+*************************************************/
+
+/* This function is called by check_auto_possessive() when a property item
+is adjacent to a fixed character.
+
+Arguments:
+ c the character
+ ptype the property type
+ pdata the data for the type
+ negated TRUE if it's a negated property (\P or \p{^)
+
+Returns: TRUE if auto-possessifying is OK
+*/
+
+static BOOL
+check_char_prop(int c, int ptype, int pdata, BOOL negated)
+{
+const ucd_record *prop = GET_UCD(c);
+switch(ptype)
+ {
+ case PT_LAMP:
+ return (prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == negated;
+
+ case PT_GC:
+ return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
+
+ case PT_PC:
+ return (pdata == prop->chartype) == negated;
+
+ case PT_SC:
+ return (pdata == prop->script) == negated;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
+
+ case PT_SPACE: /* Perl space */
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == negated;
+
+ case PT_PXSPACE: /* POSIX space */
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR)
+ == negated;
+
+ case PT_WORD:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == negated;
+ }
+return FALSE;
+}
+#endif /* SUPPORT_UCP */
+
+
+
+/*************************************************
+* Check if auto-possessifying is possible *
+*************************************************/
+
+/* This function is called for unlimited repeats of certain items, to see
+whether the next thing could possibly match the repeated item. If not, it makes
+sense to automatically possessify the repeated item.
+
+Arguments:
+ previous pointer to the repeated opcode
+ utf TRUE in UTF-8 / UTF-16 mode
+ ptr next character in pattern
+ options options bits
+ cd contains pointers to tables etc.
+
+Returns: TRUE if possessifying is wanted
+*/
+
+static BOOL
+check_auto_possessive(const pcre_uchar *previous, BOOL utf,
+ const pcre_uchar *ptr, int options, compile_data *cd)
+{
+pcre_int32 c, next;
+int op_code = *previous++;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+ {
+ for (;;)
+ {
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ if (*ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ }
+ else break;
+ }
+ }
+
+/* If the next item is one that we can handle, get its value. A non-negative
+value is a character, a negative value is an escape value. */
+
+if (*ptr == CHAR_BACKSLASH)
+ {
+ int temperrorcode = 0;
+ next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE);
+ if (temperrorcode != 0) return FALSE;
+ ptr++; /* Point after the escape sequence */
+ }
+else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
+ {
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARINC(next, ptr); } else
+#endif
+ next = *ptr++;
+ }
+else return FALSE;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+ {
+ for (;;)
+ {
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ if (*ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ }
+ else break;
+ }
+ }
+
+/* If the next thing is itself optional, we have to give up. */
+
+if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ return FALSE;
+
+/* Now compare the next item with the previous opcode. First, handle cases when
+the next item is a character. */
+
+if (next >= 0) switch(op_code)
+ {
+ case OP_CHAR:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ return c != next;
+
+ /* For CHARI (caseless character) we must check the other case. If we have
+ Unicode property support, we can use it to test the other case of
+ high-valued characters. */
+
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ if (c == next) return FALSE;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ unsigned int othercase;
+ if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE((unsigned int)next);
+#else
+ othercase = NOTACHAR;
+#endif
+ return (unsigned int)c != othercase;
+ }
+ else
+#endif /* SUPPORT_UTF */
+ return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
+
+ /* For OP_NOT and OP_NOTI, the data is always a single-byte character. These
+ opcodes are not used for multi-byte characters, because they are coded using
+ an XCLASS instead. */
+
+ case OP_NOT:
+ return (c = *previous) == next;
+
+ case OP_NOTI:
+ if ((c = *previous) == next) return TRUE;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ unsigned int othercase;
+ if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE(next);
+#else
+ othercase = NOTACHAR;
+#endif
+ return (unsigned int)c == othercase;
+ }
+ else
+#endif /* SUPPORT_UTF */
+ return (c == (int)(TABLE_GET((unsigned int)next, cd->fcc, next))); /* Non-UTF-8 mode */
+
+ /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set.
+ When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
+
+ case OP_DIGIT:
+ return next > 127 || (cd->ctypes[next] & ctype_digit) == 0;
+
+ case OP_NOT_DIGIT:
+ return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0;
+
+ case OP_WHITESPACE:
+ return next > 127 || (cd->ctypes[next] & ctype_space) == 0;
+
+ case OP_NOT_WHITESPACE:
+ return next <= 127 && (cd->ctypes[next] & ctype_space) != 0;
+
+ case OP_WORDCHAR:
+ return next > 127 || (cd->ctypes[next] & ctype_word) == 0;
+
+ case OP_NOT_WORDCHAR:
+ return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
+
+ case OP_HSPACE:
+ case OP_NOT_HSPACE:
+ switch(next)
+ {
+ case 0x09:
+ case 0x20:
+ case 0xa0:
+ case 0x1680:
+ case 0x180e:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x202f:
+ case 0x205f:
+ case 0x3000:
+ return op_code == OP_NOT_HSPACE;
+ default:
+ return op_code != OP_NOT_HSPACE;
+ }
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ case OP_NOT_VSPACE:
+ switch(next)
+ {
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x85:
+ case 0x2028:
+ case 0x2029:
+ return op_code == OP_NOT_VSPACE;
+ default:
+ return op_code != OP_NOT_VSPACE;
+ }
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ return check_char_prop(next, previous[0], previous[1], FALSE);
+
+ case OP_NOTPROP:
+ return check_char_prop(next, previous[0], previous[1], TRUE);
+#endif
+
+ default:
+ return FALSE;
+ }
+
+
+/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP
+is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are
+generated only when PCRE_UCP is *not* set, that is, when only ASCII
+characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are
+replaced by OP_PROP codes when PCRE_UCP is set. */
+
+switch(op_code)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ switch(-next)
+ {
+ case ESC_d:
+ return c > 127 || (cd->ctypes[c] & ctype_digit) == 0;
+
+ case ESC_D:
+ return c <= 127 && (cd->ctypes[c] & ctype_digit) != 0;
+
+ case ESC_s:
+ return c > 127 || (cd->ctypes[c] & ctype_space) == 0;
+
+ case ESC_S:
+ return c <= 127 && (cd->ctypes[c] & ctype_space) != 0;
+
+ case ESC_w:
+ return c > 127 || (cd->ctypes[c] & ctype_word) == 0;
+
+ case ESC_W:
+ return c <= 127 && (cd->ctypes[c] & ctype_word) != 0;
+
+ case ESC_h:
+ case ESC_H:
+ switch(c)
+ {
+ case 0x09:
+ case 0x20:
+ case 0xa0:
+ case 0x1680:
+ case 0x180e:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x202f:
+ case 0x205f:
+ case 0x3000:
+ return -next != ESC_h;
+ default:
+ return -next == ESC_h;
+ }
+
+ case ESC_v:
+ case ESC_V:
+ switch(c)
+ {
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x85:
+ case 0x2028:
+ case 0x2029:
+ return -next != ESC_v;
+ default:
+ return -next == ESC_v;
+ }
+
+ /* When PCRE_UCP is set, these values get generated for \d etc. Find
+ their substitutions and process them. The result will always be either
+ -ESC_p or -ESC_P. Then fall through to process those values. */
+
+#ifdef SUPPORT_UCP
+ case ESC_du:
+ case ESC_DU:
+ case ESC_wu:
+ case ESC_WU:
+ case ESC_su:
+ case ESC_SU:
+ {
+ int temperrorcode = 0;
+ ptr = substitutes[-next - ESC_DU];
+ next = check_escape(&ptr, &temperrorcode, 0, options, FALSE);
+ if (temperrorcode != 0) return FALSE;
+ ptr++; /* For compatibility */
+ }
+ /* Fall through */
+
+ case ESC_p:
+ case ESC_P:
+ {
+ int ptype, pdata, errorcodeptr;
+ BOOL negated;
+
+ ptr--; /* Make ptr point at the p or P */
+ ptype = get_ucp(&ptr, &negated, &pdata, &errorcodeptr);
+ if (ptype < 0) return FALSE;
+ ptr++; /* Point past the final curly ket */
+
+ /* If the property item is optional, we have to give up. (When generated
+ from \d etc by PCRE_UCP, this test will have been applied much earlier,
+ to the original \d etc. At this point, ptr will point to a zero byte. */
+
+ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ return FALSE;
+
+ /* Do the property check. */
+
+ return check_char_prop(c, ptype, pdata, (next == -ESC_P) != negated);
+ }
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ /* In principle, support for Unicode properties should be integrated here as
+ well. It means re-organizing the above code so as to get hold of the property
+ values before switching on the op-code. However, I wonder how many patterns
+ combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set,
+ these op-codes are never generated.) */
+
+ case OP_DIGIT:
+ return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
+ next == -ESC_h || next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_DIGIT:
+ return next == -ESC_d;
+
+ case OP_WHITESPACE:
+ return next == -ESC_S || next == -ESC_d || next == -ESC_w || next == -ESC_R;
+
+ case OP_NOT_WHITESPACE:
+ return next == -ESC_s || next == -ESC_h || next == -ESC_v;
+
+ case OP_HSPACE:
+ return next == -ESC_S || next == -ESC_H || next == -ESC_d ||
+ next == -ESC_w || next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_HSPACE:
+ return next == -ESC_h;
+
+ /* Can't have \S in here because VT matches \S (Perl anomaly) */
+ case OP_ANYNL:
+ case OP_VSPACE:
+ return next == -ESC_V || next == -ESC_d || next == -ESC_w;
+
+ case OP_NOT_VSPACE:
+ return next == -ESC_v || next == -ESC_R;
+
+ case OP_WORDCHAR:
+ return next == -ESC_W || next == -ESC_s || next == -ESC_h ||
+ next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_WORDCHAR:
+ return next == -ESC_w || next == -ESC_d;
+
+ default:
+ return FALSE;
+ }
+
+/* Control does not reach here */
+}
+
+
+
+/*************************************************
+* Compile one branch *
+*************************************************/
+
+/* Scan the pattern, compiling it into the a vector. If the options are
+changed during the branch, the pointer is used to change the external options
+bits. This function is used during the pre-compile phase when we are trying
+to find out the amount of memory needed, as well as during the real compile
+phase. The value of lengthptr distinguishes the two phases.
+
+Arguments:
+ optionsptr pointer to the option bits
+ codeptr points to the pointer to the current code point
+ ptrptr points to the current pattern pointer
+ errorcodeptr points to error code variable
+ firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
+ reqcharptr set to the last literal character required, else < 0
+ bcptr points to current branch chain
+ cond_depth conditional nesting depth
+ cd contains pointers to tables etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE on success
+ FALSE, with *errorcodeptr set non-zero on error
+*/
+
+static BOOL
+compile_branch(int *optionsptr, pcre_uchar **codeptr,
+ const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr,
+ pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth,
+ compile_data *cd, int *lengthptr)
+{
+int repeat_type, op_type;
+int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
+int bravalue = 0;
+int greedy_default, greedy_non_default;
+pcre_int32 firstchar, reqchar;
+pcre_int32 zeroreqchar, zerofirstchar;
+pcre_int32 req_caseopt, reqvary, tempreqvary;
+int options = *optionsptr; /* May change dynamically */
+int after_manual_callout = 0;
+int length_prevgroup = 0;
+register int c;
+register pcre_uchar *code = *codeptr;
+pcre_uchar *last_code = code;
+pcre_uchar *orig_code = code;
+pcre_uchar *tempcode;
+BOOL inescq = FALSE;
+BOOL groupsetfirstchar = FALSE;
+const pcre_uchar *ptr = *ptrptr;
+const pcre_uchar *tempptr;
+const pcre_uchar *nestptr = NULL;
+pcre_uchar *previous = NULL;
+pcre_uchar *previous_callout = NULL;
+pcre_uchar *save_hwm = NULL;
+pcre_uint8 classbits[32];
+
+/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
+must not do this for other options (e.g. PCRE_EXTENDED) because they may change
+dynamically as we process the pattern. */
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+pcre_uchar utf_chars[6];
+#else
+BOOL utf = FALSE;
+#endif
+
+/* Helper variables for OP_XCLASS opcode (for characters > 255). */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+BOOL xclass;
+pcre_uchar *class_uchardata;
+pcre_uchar *class_uchardata_base;
+#endif
+
+#ifdef PCRE_DEBUG
+if (lengthptr != NULL) DPRINTF((">> start branch\n"));
+#endif
+
+/* Set up the default and non-default settings for greediness */
+
+greedy_default = ((options & PCRE_UNGREEDY) != 0);
+greedy_non_default = greedy_default ^ 1;
+
+/* Initialize no first byte, no required byte. REQ_UNSET means "no char
+matching encountered yet". It gets changed to REQ_NONE if we hit something that
+matches a non-fixed char first char; reqchar just remains unset if we never
+find one.
+
+When we hit a repeat whose minimum is zero, we may have to adjust these values
+to take the zero repeat into account. This is implemented by setting them to
+zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual
+item types that can be repeated set these backoff variables appropriately. */
+
+firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET;
+
+/* The variable req_caseopt contains either the REQ_CASELESS value
+or zero, according to the current setting of the caseless flag. The
+REQ_CASELESS leaves the lower 28 bit empty. It is added into the
+firstchar or reqchar variables to record the case status of the
+value. This is used only for ASCII characters. */
+
+req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
+
+/* Switch on next character until the end of the branch */
+
+for (;; ptr++)
+ {
+ BOOL negate_class;
+ BOOL should_flip_negation;
+ BOOL possessive_quantifier;
+ BOOL is_quantifier;
+ BOOL is_recurse;
+ BOOL reset_bracount;
+ int class_has_8bitchar;
+ int class_single_char;
+ int newoptions;
+ int recno;
+ int refsign;
+ int skipbytes;
+ int subreqchar;
+ int subfirstchar;
+ int terminator;
+ int mclength;
+ int tempbracount;
+ pcre_uchar mcbuffer[8];
+
+ /* Get next character in the pattern */
+
+ c = *ptr;
+
+ /* If we are at the end of a nested substitution, revert to the outer level
+ string. Nesting only happens one level deep. */
+
+ if (c == 0 && nestptr != NULL)
+ {
+ ptr = nestptr;
+ nestptr = NULL;
+ c = *ptr;
+ }
+
+ /* If we are in the pre-compile phase, accumulate the length used for the
+ previous cycle of this loop. */
+
+ if (lengthptr != NULL)
+ {
+#ifdef PCRE_DEBUG
+ if (code > cd->hwm) cd->hwm = code; /* High water info */
+#endif
+ if (code > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
+ {
+ *errorcodeptr = ERR52;
+ goto FAILED;
+ }
+
+ /* There is at least one situation where code goes backwards: this is the
+ case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
+ the class is simply eliminated. However, it is created first, so we have to
+ allow memory for it. Therefore, don't ever reduce the length at this point.
+ */
+
+ if (code < last_code) code = last_code;
+
+ /* Paranoid check for integer overflow */
+
+ if (OFLOW_MAX - *lengthptr < code - last_code)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+
+ *lengthptr += (int)(code - last_code);
+ DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr,
+ (int)(code - last_code), c, c));
+
+ /* If "previous" is set and it is not at the start of the work space, move
+ it back to there, in order to avoid filling up the work space. Otherwise,
+ if "previous" is NULL, reset the current code pointer to the start. */
+
+ if (previous != NULL)
+ {
+ if (previous > orig_code)
+ {
+ memmove(orig_code, previous, IN_UCHARS(code - previous));
+ code -= previous - orig_code;
+ previous = orig_code;
+ }
+ }
+ else code = orig_code;
+
+ /* Remember where this code item starts so we can pick up the length
+ next time round. */
+
+ last_code = code;
+ }
+
+ /* In the real compile phase, just check the workspace used by the forward
+ reference list. */
+
+ else if (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
+ {
+ *errorcodeptr = ERR52;
+ goto FAILED;
+ }
+
+ /* If in \Q...\E, check for the end; if not, we have a literal */
+
+ if (inescq && c != 0)
+ {
+ if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+ {
+ inescq = FALSE;
+ ptr++;
+ continue;
+ }
+ else
+ {
+ if (previous_callout != NULL)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+ if ((options & PCRE_AUTO_CALLOUT) != 0)
+ {
+ previous_callout = code;
+ code = auto_callout(code, ptr, cd);
+ }
+ goto NORMAL_CHAR;
+ }
+ }
+
+ /* Fill in length of a previous callout, except when the next thing is
+ a quantifier. */
+
+ is_quantifier =
+ c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
+ (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
+
+ if (!is_quantifier && previous_callout != NULL &&
+ after_manual_callout-- <= 0)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+
+ /* In extended mode, skip white space and comments. */
+
+ if ((options & PCRE_EXTENDED) != 0)
+ {
+ if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
+ if (c == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ if (*ptr != 0) continue;
+
+ /* Else fall through to handle end of string */
+ c = 0;
+ }
+ }
+
+ /* No auto callout for quantifiers. */
+
+ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
+ {
+ previous_callout = code;
+ code = auto_callout(code, ptr, cd);
+ }
+
+ switch(c)
+ {
+ /* ===================================================================*/
+ case 0: /* The branch terminates at string end */
+ case CHAR_VERTICAL_LINE: /* or | or ) */
+ case CHAR_RIGHT_PARENTHESIS:
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
+ *codeptr = code;
+ *ptrptr = ptr;
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < code - last_code)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += (int)(code - last_code); /* To include callout length */
+ DPRINTF((">> end branch\n"));
+ }
+ return TRUE;
+
+
+ /* ===================================================================*/
+ /* Handle single-character metacharacters. In multiline mode, ^ disables
+ the setting of any following char as a first character. */
+
+ case CHAR_CIRCUMFLEX_ACCENT:
+ previous = NULL;
+ if ((options & PCRE_MULTILINE) != 0)
+ {
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ *code++ = OP_CIRCM;
+ }
+ else *code++ = OP_CIRC;
+ break;
+
+ case CHAR_DOLLAR_SIGN:
+ previous = NULL;
+ *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
+ break;
+
+ /* There can never be a first char if '.' is first, whatever happens about
+ repeats. The value of reqchar doesn't change either. */
+
+ case CHAR_DOT:
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+ previous = code;
+ *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
+ break;
+
+
+ /* ===================================================================*/
+ /* Character classes. If the included characters are all < 256, we build a
+ 32-byte bitmap of the permitted characters, except in the special case
+ where there is only one such character. For negated classes, we build the
+ map as usual, then invert it at the end. However, we use a different opcode
+ so that data characters > 255 can be handled correctly.
+
+ If the class contains characters outside the 0-255 range, a different
+ opcode is compiled. It may optionally have a bit map for characters < 256,
+ but those above are are explicitly listed afterwards. A flag byte tells
+ whether the bitmap is present, and whether this is a negated class or not.
+
+ In JavaScript compatibility mode, an isolated ']' causes an error. In
+ default (Perl) mode, it is treated as a data character. */
+
+ case CHAR_RIGHT_SQUARE_BRACKET:
+ if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ *errorcodeptr = ERR64;
+ goto FAILED;
+ }
+ goto NORMAL_CHAR;
+
+ case CHAR_LEFT_SQUARE_BRACKET:
+ previous = code;
+
+ /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
+ they are encountered at the top level, so we'll do that too. */
+
+ if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, &tempptr))
+ {
+ *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31;
+ goto FAILED;
+ }
+
+ /* If the first character is '^', set the negation flag and skip it. Also,
+ if the first few characters (either before or after ^) are \Q\E or \E we
+ skip them too. This makes for compatibility with Perl. */
+
+ negate_class = FALSE;
+ for (;;)
+ {
+ c = *(++ptr);
+ if (c == CHAR_BACKSLASH)
+ {
+ if (ptr[1] == CHAR_E)
+ ptr++;
+ else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ ptr += 3;
+ else
+ break;
+ }
+ else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
+ negate_class = TRUE;
+ else break;
+ }
+
+ /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
+ an initial ']' is taken as a data character -- the code below handles
+ that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
+ [^] must match any character, so generate OP_ALLANY. */
+
+ if (c == CHAR_RIGHT_SQUARE_BRACKET &&
+ (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ *code++ = negate_class? OP_ALLANY : OP_FAIL;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ break;
+ }
+
+ /* If a class contains a negative special such as \S, we need to flip the
+ negation flag at the end, so that support for characters > 255 works
+ correctly (they are all included in the class). */
+
+ should_flip_negation = FALSE;
+
+ /* For optimization purposes, we track some properties of the class.
+ class_has_8bitchar will be non-zero, if the class contains at least one
+ < 256 character. class_single_char will be 1 if the class contains only
+ a single character. */
+
+ class_has_8bitchar = 0;
+ class_single_char = 0;
+
+ /* Initialize the 32-char bit map to all zeros. We build the map in a
+ temporary bit of memory, in case the class contains only 1 character (less
+ than 256), because in that case the compiled code doesn't use the bit map.
+ */
+
+ memset(classbits, 0, 32 * sizeof(pcre_uint8));
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ xclass = FALSE; /* No chars >= 256 */
+ class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */
+ class_uchardata_base = class_uchardata; /* For resetting in pass 1 */
+#endif
+
+ /* Process characters until ] is reached. By writing this as a "do" it
+ means that an initial ] is taken as a data character. At the start of the
+ loop, c contains the first byte of the character. */
+
+ if (c != 0) do
+ {
+ const pcre_uchar *oldptr;
+
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
+ { /* Braces are required because the */
+ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
+ }
+#endif
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ /* In the pre-compile phase, accumulate the length of any extra
+ data and reset the pointer. This is so that very large classes that
+ contain a zillion > 255 characters no longer overwrite the work space
+ (which is on the stack). */
+
+ if (lengthptr != NULL)
+ {
+ *lengthptr += class_uchardata - class_uchardata_base;
+ class_uchardata = class_uchardata_base;
+ }
+#endif
+
+ /* Inside \Q...\E everything is literal except \E */
+
+ if (inescq)
+ {
+ if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */
+ {
+ inescq = FALSE; /* Reset literal state */
+ ptr++; /* Skip the 'E' */
+ continue; /* Carry on with next */
+ }
+ goto CHECK_RANGE; /* Could be range if \E follows */
+ }
+
+ /* Handle POSIX class names. Perl allows a negation extension of the
+ form [:^name:]. A square bracket that doesn't match the syntax is
+ treated as a literal. We also recognize the POSIX constructions
+ [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
+ 5.6 and 5.8 do. */
+
+ if (c == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
+ {
+ BOOL local_negate = FALSE;
+ int posix_class, taboffset, tabopt;
+ register const pcre_uint8 *cbits = cd->cbits;
+ pcre_uint8 pbits[32];
+
+ if (ptr[1] != CHAR_COLON)
+ {
+ *errorcodeptr = ERR31;
+ goto FAILED;
+ }
+
+ ptr += 2;
+ if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ local_negate = TRUE;
+ should_flip_negation = TRUE; /* Note negative special */
+ ptr++;
+ }
+
+ posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
+ if (posix_class < 0)
+ {
+ *errorcodeptr = ERR30;
+ goto FAILED;
+ }
+
+ /* If matching is caseless, upper and lower are converted to
+ alpha. This relies on the fact that the class table starts with
+ alpha, lower, upper as the first 3 entries. */
+
+ if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
+ posix_class = 0;
+
+ /* When PCRE_UCP is set, some of the POSIX classes are converted to
+ different escape sequences that use Unicode properties. */
+
+#ifdef SUPPORT_UCP
+ if ((options & PCRE_UCP) != 0)
+ {
+ int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
+ if (posix_substitutes[pc] != NULL)
+ {
+ nestptr = tempptr + 1;
+ ptr = posix_substitutes[pc] - 1;
+ continue;
+ }
+ }
+#endif
+ /* In the non-UCP case, we build the bit map for the POSIX class in a
+ chunk of local store because we may be adding and subtracting from it,
+ and we don't want to subtract bits that may be in the main map already.
+ At the end we or the result into the bit map that is being built. */
+
+ posix_class *= 3;
+
+ /* Copy in the first table (always present) */
+
+ memcpy(pbits, cbits + posix_class_maps[posix_class],
+ 32 * sizeof(pcre_uint8));
+
+ /* If there is a second table, add or remove it as required. */
+
+ taboffset = posix_class_maps[posix_class + 1];
+ tabopt = posix_class_maps[posix_class + 2];
+
+ if (taboffset >= 0)
+ {
+ if (tabopt >= 0)
+ for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
+ else
+ for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
+ }
+
+ /* Not see if we need to remove any special characters. An option
+ value of 1 removes vertical space and 2 removes underscore. */
+
+ if (tabopt < 0) tabopt = -tabopt;
+ if (tabopt == 1) pbits[1] &= ~0x3c;
+ else if (tabopt == 2) pbits[11] &= 0x7f;
+
+ /* Add the POSIX table or its complement into the main table that is
+ being built and we are done. */
+
+ if (local_negate)
+ for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
+ else
+ for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
+
+ ptr = tempptr + 1;
+ /* Every class contains at least one < 256 characters. */
+ class_has_8bitchar = 1;
+ /* Every class contains at least two characters. */
+ class_single_char = 2;
+ continue; /* End of POSIX syntax handling */
+ }
+
+ /* Backslash may introduce a single character, or it may introduce one
+ of the specials, which just set a flag. The sequence \b is a special
+ case. Inside a class (and only there) it is treated as backspace. We
+ assume that other escapes have more than one character in them, so
+ speculatively set both class_has_8bitchar and class_single_char bigger
+ than one. Unrecognized escapes fall through and are either treated
+ as literal characters (by default), or are faulted if
+ PCRE_EXTRA is set. */
+
+ if (c == CHAR_BACKSLASH)
+ {
+ c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
+ else if (-c == ESC_N) /* \N is not supported in a class */
+ {
+ *errorcodeptr = ERR71;
+ goto FAILED;
+ }
+ else if (-c == ESC_Q) /* Handle start of quoted string */
+ {
+ if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ {
+ ptr += 2; /* avoid empty string */
+ }
+ else inescq = TRUE;
+ continue;
+ }
+ else if (-c == ESC_E) continue; /* Ignore orphan \E */
+
+ if (c < 0)
+ {
+ register const pcre_uint8 *cbits = cd->cbits;
+ /* Every class contains at least two < 256 characters. */
+ class_has_8bitchar++;
+ /* Every class contains at least two characters. */
+ class_single_char += 2;
+
+ switch (-c)
+ {
+#ifdef SUPPORT_UCP
+ case ESC_du: /* These are the values given for \d etc */
+ case ESC_DU: /* when PCRE_UCP is set. We replace the */
+ case ESC_wu: /* escape sequence with an appropriate \p */
+ case ESC_WU: /* or \P to test Unicode properties instead */
+ case ESC_su: /* of the default ASCII testing. */
+ case ESC_SU:
+ nestptr = ptr;
+ ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
+ class_has_8bitchar--; /* Undo! */
+ continue;
+#endif
+ case ESC_d:
+ for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
+ continue;
+
+ case ESC_D:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
+ continue;
+
+ case ESC_w:
+ for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
+ continue;
+
+ case ESC_W:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
+ continue;
+
+ /* Perl 5.004 onwards omits VT from \s, but we must preserve it
+ if it was previously set by something earlier in the character
+ class. */
+
+ case ESC_s:
+ classbits[0] |= cbits[cbit_space];
+ classbits[1] |= cbits[cbit_space+1] & ~0x08;
+ for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
+ continue;
+
+ case ESC_S:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
+ classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
+ continue;
+
+ case ESC_h:
+ SETBIT(classbits, 0x09); /* VT */
+ SETBIT(classbits, 0x20); /* SPACE */
+ SETBIT(classbits, 0xa0); /* NSBP */
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x1680;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x180e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2000;
+ *class_uchardata++ = 0x200a;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x202f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x205f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x3000;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_H:
+ for (c = 0; c < 32; c++)
+ {
+ int x = 0xff;
+ switch (c)
+ {
+ case 0x09/8: x ^= 1 << (0x09%8); break;
+ case 0x20/8: x ^= 1 << (0x20%8); break;
+ case 0xa0/8: x ^= 1 << (0xa0%8); break;
+ default: break;
+ }
+ classbits[c] |= x;
+ }
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x167f;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x1681;
+ *class_uchardata++ = 0x180d;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x180f;
+ *class_uchardata++ = 0x1fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x200b;
+ *class_uchardata++ = 0x202e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2030;
+ *class_uchardata++ = 0x205e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2060;
+ *class_uchardata++ = 0x2fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x3001;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_v:
+ SETBIT(classbits, 0x0a); /* LF */
+ SETBIT(classbits, 0x0b); /* VT */
+ SETBIT(classbits, 0x0c); /* FF */
+ SETBIT(classbits, 0x0d); /* CR */
+ SETBIT(classbits, 0x85); /* NEL */
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2028;
+ *class_uchardata++ = 0x2029;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_V:
+ for (c = 0; c < 32; c++)
+ {
+ int x = 0xff;
+ switch (c)
+ {
+ case 0x0a/8: x ^= 1 << (0x0a%8);
+ x ^= 1 << (0x0b%8);
+ x ^= 1 << (0x0c%8);
+ x ^= 1 << (0x0d%8);
+ break;
+ case 0x85/8: x ^= 1 << (0x85%8); break;
+ default: break;
+ }
+ classbits[c] |= x;
+ }
+
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x2027;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x202a;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ }
+#endif
+ continue;
+
+#ifdef SUPPORT_UCP
+ case ESC_p:
+ case ESC_P:
+ {
+ BOOL negated;
+ int pdata;
+ int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+ if (ptype < 0) goto FAILED;
+ xclass = TRUE;
+ *class_uchardata++ = ((-c == ESC_p) != negated)?
+ XCL_PROP : XCL_NOTPROP;
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = pdata;
+ class_has_8bitchar--; /* Undo! */
+ continue;
+ }
+#endif
+ /* Unrecognized escapes are faulted if PCRE is running in its
+ strict mode. By default, for compatibility with Perl, they are
+ treated as literals. */
+
+ default:
+ if ((options & PCRE_EXTRA) != 0)
+ {
+ *errorcodeptr = ERR7;
+ goto FAILED;
+ }
+ class_has_8bitchar--; /* Undo the speculative increase. */
+ class_single_char -= 2; /* Undo the speculative increase. */
+ c = *ptr; /* Get the final character and fall through */
+ break;
+ }
+ }
+
+ /* Fall through if we have a single character (c >= 0). This may be
+ greater than 256. */
+
+ } /* End of backslash handling */
+
+ /* A single character may be followed by '-' to form a range. However,
+ Perl does not permit ']' to be the end of the range. A '-' character
+ at the end is treated as a literal. Perl ignores orphaned \E sequences
+ entirely. The code for handling \Q and \E is messy. */
+
+ CHECK_RANGE:
+ while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ {
+ inescq = FALSE;
+ ptr += 2;
+ }
+
+ oldptr = ptr;
+
+ /* Remember \r or \n */
+
+ if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Check for range */
+
+ if (!inescq && ptr[1] == CHAR_MINUS)
+ {
+ int d;
+ ptr += 2;
+ while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
+
+ /* If we hit \Q (not followed by \E) at this point, go into escaped
+ mode. */
+
+ while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
+ {
+ ptr += 2;
+ if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+ { ptr += 2; continue; }
+ inescq = TRUE;
+ break;
+ }
+
+ if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
+ {
+ ptr = oldptr;
+ goto LONE_SINGLE_CHARACTER;
+ }
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ { /* Braces are required because the */
+ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
+ }
+ else
+#endif
+ d = *ptr; /* Not UTF-8 mode */
+
+ /* The second part of a range can be a single-character escape, but
+ not any of the other escapes. Perl 5.6 treats a hyphen as a literal
+ in such circumstances. */
+
+ if (!inescq && d == CHAR_BACKSLASH)
+ {
+ d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ /* \b is backspace; any other special means the '-' was literal */
+
+ if (d < 0)
+ {
+ if (d == -ESC_b) d = CHAR_BS; else
+ {
+ ptr = oldptr;
+ goto LONE_SINGLE_CHARACTER; /* A few lines below */
+ }
+ }
+ }
+
+ /* Check that the two values are in the correct order. Optimize
+ one-character ranges */
+
+ if (d < c)
+ {
+ *errorcodeptr = ERR8;
+ goto FAILED;
+ }
+
+ if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */
+
+ /* Remember \r or \n */
+
+ if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Since we found a character range, single character optimizations
+ cannot be done anymore. */
+ class_single_char = 2;
+
+ /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
+ matching, we have to use an XCLASS with extra data items. Caseless
+ matching for characters > 127 is available only if UCP support is
+ available. */
+
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (d > 255)
+#endif
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ {
+ xclass = TRUE;
+
+ /* With UCP support, we can find the other case equivalents of
+ the relevant characters. There may be several ranges. Optimize how
+ they fit with the basic range. */
+
+#ifdef SUPPORT_UCP
+#ifndef COMPILE_PCRE8
+ if (utf && (options & PCRE_CASELESS) != 0)
+#else
+ if ((options & PCRE_CASELESS) != 0)
+#endif
+ {
+ unsigned int occ, ocd;
+ unsigned int cc = c;
+ unsigned int origd = d;
+ while (get_othercase_range(&cc, origd, &occ, &ocd))
+ {
+ if (occ >= (unsigned int)c &&
+ ocd <= (unsigned int)d)
+ continue; /* Skip embedded ranges */
+
+ if (occ < (unsigned int)c &&
+ ocd >= (unsigned int)c - 1) /* Extend the basic range */
+ { /* if there is overlap, */
+ c = occ; /* noting that if occ < c */
+ continue; /* we can't have ocd > d */
+ } /* because a subrange is */
+ if (ocd > (unsigned int)d &&
+ occ <= (unsigned int)d + 1) /* always shorter than */
+ { /* the basic range. */
+ d = ocd;
+ continue;
+ }
+
+ if (occ == ocd)
+ {
+ *class_uchardata++ = XCL_SINGLE;
+ }
+ else
+ {
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(occ, class_uchardata);
+ }
+ class_uchardata += PRIV(ord2utf)(ocd, class_uchardata);
+ }
+ }
+#endif /* SUPPORT_UCP */
+
+ /* Now record the original range, possibly modified for UCP caseless
+ overlapping ranges. */
+
+ *class_uchardata++ = XCL_RANGE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ if (utf)
+ {
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+ }
+ else
+ {
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+ }
+#else
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+#endif
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+#endif /* SUPPORT_UTF */
+
+ /* With UCP support, we are done. Without UCP support, there is no
+ caseless matching for UTF characters > 127; we can use the bit map
+ for the smaller ones. As for 16 bit characters without UTF, we
+ can still use */
+
+#ifdef SUPPORT_UCP
+#ifndef COMPILE_PCRE8
+ if (utf)
+#endif
+ continue; /* With next character in the class */
+#endif /* SUPPORT_UCP */
+
+#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8)
+ if (utf)
+ {
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 127;
+ }
+ else
+ {
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+ }
+#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP)
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 127;
+#else
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */
+ }
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+
+ /* We use the bit map for 8 bit mode, or when the characters fall
+ partially or entirely to [0-255] ([0-127] for UCP) ranges. */
+
+ class_has_8bitchar = 1;
+
+ /* We can save a bit of time by skipping this in the pre-compile. */
+
+ if (lengthptr == NULL) for (; c <= d; c++)
+ {
+ classbits[c/8] |= (1 << (c&7));
+ if ((options & PCRE_CASELESS) != 0)
+ {
+ int uc = cd->fcc[c]; /* flip case */
+ classbits[uc/8] |= (1 << (uc&7));
+ }
+ }
+
+ continue; /* Go get the next char in the class */
+ }
+
+ /* Handle a lone single character - we can get here for a normal
+ non-escape char, or after \ that introduces a single character or for an
+ apparent range that isn't. */
+
+ LONE_SINGLE_CHARACTER:
+
+ /* Only the value of 1 matters for class_single_char. */
+ if (class_single_char < 2) class_single_char++;
+
+ /* If class_charcount is 1, we saw precisely one character. As long as
+ there were no negated characters >= 128 and there was no use of \p or \P,
+ in other words, no use of any XCLASS features, we can optimize.
+
+ In UTF-8 mode, we can optimize the negative case only if there were no
+ characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
+ operate on single-bytes characters only. This is an historical hangover.
+ Maybe one day we can tidy these opcodes to handle multi-byte characters.
+
+ The optimization throws away the bit map. We turn the item into a
+ 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative.
+ Note that OP_NOT[I] does not support multibyte characters. In the positive
+ case, it can cause firstchar to be set. Otherwise, there can be no first
+ char if this item is first, whatever repeat count may follow. In the case
+ of reqchar, save the previous value for reinstating. */
+
+#ifdef SUPPORT_UTF
+ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET
+ && (!utf || !negate_class || c < (MAX_VALUE_FOR_SINGLE_CHAR + 1)))
+#else
+ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+#endif
+ {
+ ptr++;
+ zeroreqchar = reqchar;
+
+ /* The OP_NOT[I] opcodes work on single characters only. */
+
+ if (negate_class)
+ {
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT;
+ *code++ = c;
+ goto NOT_CHAR;
+ }
+
+ /* For a single, positive character, get the value into mcbuffer, and
+ then we can handle this with the normal one-character code. */
+
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
+ else
+#endif
+ {
+ mcbuffer[0] = c;
+ mclength = 1;
+ }
+ goto ONE_CHAR;
+ } /* End of 1-char optimization */
+
+ /* Handle a character that cannot go in the bit map. */
+
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (c > 255)
+#endif
+
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (!utf)
+ *class_uchardata++ = c;
+ else
+#endif
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+#endif /* SUPPORT_UTF */
+
+#ifdef SUPPORT_UCP
+#ifdef COMPILE_PCRE8
+ if ((options & PCRE_CASELESS) != 0)
+#else
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (utf && (options & PCRE_CASELESS) != 0)
+#endif
+ {
+ unsigned int othercase;
+ if ((int)(othercase = UCD_OTHERCASE(c)) != c)
+ {
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(othercase, class_uchardata);
+ }
+ }
+#endif /* SUPPORT_UCP */
+
+ }
+ else
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+
+ /* Handle a single-byte character */
+ {
+ class_has_8bitchar = 1;
+ classbits[c/8] |= (1 << (c&7));
+ if ((options & PCRE_CASELESS) != 0)
+ {
+ c = cd->fcc[c]; /* flip case */
+ classbits[c/8] |= (1 << (c&7));
+ }
+ }
+ }
+
+ /* Loop until ']' reached. This "while" is the end of the "do" far above.
+ If we are at the end of an internal nested string, revert to the outer
+ string. */
+
+ while (((c = *(++ptr)) != 0 ||
+ (nestptr != NULL &&
+ (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != 0)) &&
+ (c != CHAR_RIGHT_SQUARE_BRACKET || inescq));
+
+ /* Check for missing terminating ']' */
+
+ if (c == 0)
+ {
+ *errorcodeptr = ERR6;
+ goto FAILED;
+ }
+
+ /* If this is the first thing in the branch, there can be no first char
+ setting, whatever the repeat count. Any reqchar setting must remain
+ unchanged after any kind of repeat. */
+
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+
+ /* If there are characters with values > 255, we have to compile an
+ extended class, with its own opcode, unless there was a negated special
+ such as \S in the class, and PCRE_UCP is not set, because in that case all
+ characters > 255 are in the class, so any that were explicitly given as
+ well can be ignored. If (when there are explicit characters > 255 that must
+ be listed) there are no characters < 256, we can omit the bitmap in the
+ actual compiled code. */
+
+#ifdef SUPPORT_UTF
+ if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
+#elif !defined COMPILE_PCRE8
+ if (xclass && !should_flip_negation)
+#endif
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ {
+ *class_uchardata++ = XCL_END; /* Marks the end of extra data */
+ *code++ = OP_XCLASS;
+ code += LINK_SIZE;
+ *code = negate_class? XCL_NOT:0;
+
+ /* If the map is required, move up the extra data to make room for it;
+ otherwise just move the code pointer to the end of the extra data. */
+
+ if (class_has_8bitchar > 0)
+ {
+ *code++ |= XCL_MAP;
+ memmove(code + (32 / sizeof(pcre_uchar)), code,
+ IN_UCHARS(class_uchardata - code));
+ memcpy(code, classbits, 32);
+ code = class_uchardata + (32 / sizeof(pcre_uchar));
+ }
+ else code = class_uchardata;
+
+ /* Now fill in the complete length of the item */
+
+ PUT(previous, 1, (int)(code - previous));
+ break; /* End of class handling */
+ }
+#endif
+
+ /* If there are no characters > 255, or they are all to be included or
+ excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
+ whole class was negated and whether there were negative specials such as \S
+ (non-UCP) in the class. Then copy the 32-byte map into the code vector,
+ negating it if necessary. */
+
+ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
+ if (lengthptr == NULL) /* Save time in the pre-compile phase */
+ {
+ if (negate_class)
+ for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
+ memcpy(code, classbits, 32);
+ }
+ code += 32 / sizeof(pcre_uchar);
+ NOT_CHAR:
+ break;
+
+
+ /* ===================================================================*/
+ /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
+ has been tested above. */
+
+ case CHAR_LEFT_CURLY_BRACKET:
+ if (!is_quantifier) goto NORMAL_CHAR;
+ ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
+ if (*errorcodeptr != 0) goto FAILED;
+ goto REPEAT;
+
+ case CHAR_ASTERISK:
+ repeat_min = 0;
+ repeat_max = -1;
+ goto REPEAT;
+
+ case CHAR_PLUS:
+ repeat_min = 1;
+ repeat_max = -1;
+ goto REPEAT;
+
+ case CHAR_QUESTION_MARK:
+ repeat_min = 0;
+ repeat_max = 1;
+
+ REPEAT:
+ if (previous == NULL)
+ {
+ *errorcodeptr = ERR9;
+ goto FAILED;
+ }
+
+ if (repeat_min == 0)
+ {
+ firstchar = zerofirstchar; /* Adjust for zero repeat */
+ reqchar = zeroreqchar; /* Ditto */
+ }
+
+ /* Remember whether this is a variable length repeat */
+
+ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
+
+ op_type = 0; /* Default single-char op codes */
+ possessive_quantifier = FALSE; /* Default not possessive quantifier */
+
+ /* Save start of previous item, in case we have to move it up in order to
+ insert something before it. */
+
+ tempcode = previous;
+
+ /* If the next character is '+', we have a possessive quantifier. This
+ implies greediness, whatever the setting of the PCRE_UNGREEDY option.
+ If the next character is '?' this is a minimizing repeat, by default,
+ but if PCRE_UNGREEDY is set, it works the other way round. We change the
+ repeat type to the non-default. */
+
+ if (ptr[1] == CHAR_PLUS)
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ ptr++;
+ }
+ else if (ptr[1] == CHAR_QUESTION_MARK)
+ {
+ repeat_type = greedy_non_default;
+ ptr++;
+ }
+ else repeat_type = greedy_default;
+
+ /* If previous was a recursion call, wrap it in atomic brackets so that
+ previous becomes the atomic group. All recursions were so wrapped in the
+ past, but it no longer happens for non-repeated recursions. In fact, the
+ repeated ones could be re-implemented independently so as not to need this,
+ but for the moment we rely on the code for repeating groups. */
+
+ if (*previous == OP_RECURSE)
+ {
+ memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE));
+ *previous = OP_ONCE;
+ PUT(previous, 1, 2 + 2*LINK_SIZE);
+ previous[2 + 2*LINK_SIZE] = OP_KET;
+ PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+ code += 2 + 2 * LINK_SIZE;
+ length_prevgroup = 3 + 3*LINK_SIZE;
+
+ /* When actually compiling, we need to check whether this was a forward
+ reference, and if so, adjust the offset. */
+
+ if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
+ {
+ int offset = GET(cd->hwm, -LINK_SIZE);
+ if (offset == previous + 1 - cd->start_code)
+ PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
+ }
+ }
+
+ /* Now handle repetition for the different types of item. */
+
+ /* If previous was a character match, abolish the item and generate a
+ repeat item instead. If a char item has a minumum of more than one, ensure
+ that it is set in reqchar - it might not be if a sequence such as x{3} is
+ the first thing in a branch because the x will have gone into firstchar
+ instead. */
+
+ if (*previous == OP_CHAR || *previous == OP_CHARI)
+ {
+ op_type = (*previous == OP_CHAR)? 0 : OP_STARI - OP_STAR;
+
+ /* Deal with UTF characters that take up more than one character. It's
+ easier to write this out separately than try to macrify it. Use c to
+ hold the length of the character in bytes, plus UTF_LENGTH to flag that
+ it's a length rather than a small character. */
+
+#ifdef SUPPORT_UTF
+ if (utf && NOT_FIRSTCHAR(code[-1]))
+ {
+ pcre_uchar *lastchar = code - 1;
+ BACKCHAR(lastchar);
+ c = (int)(code - lastchar); /* Length of UTF-8 character */
+ memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */
+ c |= UTF_LENGTH; /* Flag c as a length */
+ }
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Handle the case of a single charater - either with no UTF support, or
+ with UTF disabled, or for a single character UTF character. */
+ {
+ c = code[-1];
+ if (repeat_min > 1) reqchar = c | req_caseopt | cd->req_varyopt;
+ }
+
+ /* If the repetition is unlimited, it pays to see if the next thing on
+ the line is something that cannot possibly match this character. If so,
+ automatically possessifying this item gains some performance in the case
+ where the match fails. */
+
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+
+ goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
+ }
+
+ /* If previous was a single negated character ([^a] or similar), we use
+ one of the special opcodes, replacing it. The code is shared with single-
+ character repeats by setting opt_type to add a suitable offset into
+ repeat_type. We can also test for auto-possessification. OP_NOT and OP_NOTI
+ are currently used only for single-byte chars. */
+
+ else if (*previous == OP_NOT || *previous == OP_NOTI)
+ {
+ op_type = ((*previous == OP_NOT)? OP_NOTSTAR : OP_NOTSTARI) - OP_STAR;
+ c = previous[1];
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+ goto OUTPUT_SINGLE_REPEAT;
+ }
+
+ /* If previous was a character type match (\d or similar), abolish it and
+ create a suitable repeat item. The code is shared with single-character
+ repeats by setting op_type to add a suitable offset into repeat_type. Note
+ the the Unicode property types will be present only when SUPPORT_UCP is
+ defined, but we don't wrap the little bits of code here because it just
+ makes it horribly messy. */
+
+ else if (*previous < OP_EODN)
+ {
+ pcre_uchar *oldcode;
+ int prop_type, prop_value;
+ op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
+ c = *previous;
+
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+
+ OUTPUT_SINGLE_REPEAT:
+ if (*previous == OP_PROP || *previous == OP_NOTPROP)
+ {
+ prop_type = previous[1];
+ prop_value = previous[2];
+ }
+ else prop_type = prop_value = -1;
+
+ oldcode = code;
+ code = previous; /* Usually overwrite previous item */
+
+ /* If the maximum is zero then the minimum must also be zero; Perl allows
+ this case, so we do too - by simply omitting the item altogether. */
+
+ if (repeat_max == 0) goto END_REPEAT;
+
+ /*--------------------------------------------------------------------*/
+ /* This code is obsolete from release 8.00; the restriction was finally
+ removed: */
+
+ /* All real repeats make it impossible to handle partial matching (maybe
+ one day we will be able to remove this restriction). */
+
+ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+ /*--------------------------------------------------------------------*/
+
+ /* Combine the op_type with the repeat_type */
+
+ repeat_type += op_type;
+
+ /* A minimum of zero is handled either as the special case * or ?, or as
+ an UPTO, with the maximum given. */
+
+ if (repeat_min == 0)
+ {
+ if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
+ else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+
+ /* A repeat minimum of 1 is optimized into some special cases. If the
+ maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
+ left in place and, if the maximum is greater than 1, we use OP_UPTO with
+ one less than the maximum. */
+
+ else if (repeat_min == 1)
+ {
+ if (repeat_max == -1)
+ *code++ = OP_PLUS + repeat_type;
+ else
+ {
+ code = oldcode; /* leave previous item in place */
+ if (repeat_max == 1) goto END_REPEAT;
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max - 1);
+ }
+ }
+
+ /* The case {n,n} is just an EXACT, while the general case {n,m} is
+ handled as an EXACT followed by an UPTO. */
+
+ else
+ {
+ *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
+ PUT2INC(code, 0, repeat_min);
+
+ /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
+ we have to insert the character for the previous code. For a repeated
+ Unicode property match, there are two extra bytes that define the
+ required property. In UTF-8 mode, long characters have their length in
+ c, with the UTF_LENGTH bit as a flag. */
+
+ if (repeat_max < 0)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ {
+ *code++ = c;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ }
+ *code++ = OP_STAR + repeat_type;
+ }
+
+ /* Else insert an UPTO if the max is greater than the min, again
+ preceded by the character, for the previously inserted code. If the
+ UPTO is just for 1 instance, we can use QUERY instead. */
+
+ else if (repeat_max != repeat_min)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ *code++ = c;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ repeat_max -= repeat_min;
+
+ if (repeat_max == 1)
+ {
+ *code++ = OP_QUERY + repeat_type;
+ }
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+ }
+
+ /* The character or character type itself comes last in all cases. */
+
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ *code++ = c;
+
+ /* For a repeated Unicode property match, there are two extra bytes that
+ define the required property. */
+
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+#endif
+ }
+
+ /* If previous was a character class or a back reference, we put the repeat
+ stuff after it, but just skip the item if the repeat was {0,0}. */
+
+ else if (*previous == OP_CLASS ||
+ *previous == OP_NCLASS ||
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ *previous == OP_XCLASS ||
+#endif
+ *previous == OP_REF ||
+ *previous == OP_REFI)
+ {
+ if (repeat_max == 0)
+ {
+ code = previous;
+ goto END_REPEAT;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* This code is obsolete from release 8.00; the restriction was finally
+ removed: */
+
+ /* All real repeats make it impossible to handle partial matching (maybe
+ one day we will be able to remove this restriction). */
+
+ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+ /*--------------------------------------------------------------------*/
+
+ if (repeat_min == 0 && repeat_max == -1)
+ *code++ = OP_CRSTAR + repeat_type;
+ else if (repeat_min == 1 && repeat_max == -1)
+ *code++ = OP_CRPLUS + repeat_type;
+ else if (repeat_min == 0 && repeat_max == 1)
+ *code++ = OP_CRQUERY + repeat_type;
+ else
+ {
+ *code++ = OP_CRRANGE + repeat_type;
+ PUT2INC(code, 0, repeat_min);
+ if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+
+ /* If previous was a bracket group, we may have to replicate it in certain
+ cases. Note that at this point we can encounter only the "basic" bracket
+ opcodes such as BRA and CBRA, as this is the place where they get converted
+ into the more special varieties such as BRAPOS and SBRA. A test for >=
+ OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
+ ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow
+ repetition of assertions, but now it does, for Perl compatibility. */
+
+ else if (*previous >= OP_ASSERT && *previous <= OP_COND)
+ {
+ register int i;
+ int len = (int)(code - previous);
+ pcre_uchar *bralink = NULL;
+ pcre_uchar *brazeroptr = NULL;
+
+ /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so
+ we just ignore the repeat. */
+
+ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
+ goto END_REPEAT;
+
+ /* There is no sense in actually repeating assertions. The only potential
+ use of repetition is in cases when the assertion is optional. Therefore,
+ if the minimum is greater than zero, just ignore the repeat. If the
+ maximum is not not zero or one, set it to 1. */
+
+ if (*previous < OP_ONCE) /* Assertion */
+ {
+ if (repeat_min > 0) goto END_REPEAT;
+ if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
+ }
+
+ /* The case of a zero minimum is special because of the need to stick
+ OP_BRAZERO in front of it, and because the group appears once in the
+ data, whereas in other cases it appears the minimum number of times. For
+ this reason, it is simplest to treat this case separately, as otherwise
+ the code gets far too messy. There are several special subcases when the
+ minimum is zero. */
+
+ if (repeat_min == 0)
+ {
+ /* If the maximum is also zero, we used to just omit the group from the
+ output altogether, like this:
+
+ ** if (repeat_max == 0)
+ ** {
+ ** code = previous;
+ ** goto END_REPEAT;
+ ** }
+
+ However, that fails when a group or a subgroup within it is referenced
+ as a subroutine from elsewhere in the pattern, so now we stick in
+ OP_SKIPZERO in front of it so that it is skipped on execution. As we
+ don't have a list of which groups are referenced, we cannot do this
+ selectively.
+
+ If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
+ and do no more at this point. However, we do need to adjust any
+ OP_RECURSE calls inside the group that refer to the group itself or any
+ internal or forward referenced group, because the offset is from the
+ start of the whole regex. Temporarily terminate the pattern while doing
+ this. */
+
+ if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
+ {
+ *code = OP_END;
+ adjust_recurse(previous, 1, utf, cd, save_hwm);
+ memmove(previous + 1, previous, IN_UCHARS(len));
+ code++;
+ if (repeat_max == 0)
+ {
+ *previous++ = OP_SKIPZERO;
+ goto END_REPEAT;
+ }
+ brazeroptr = previous; /* Save for possessive optimizing */
+ *previous++ = OP_BRAZERO + repeat_type;
+ }
+
+ /* If the maximum is greater than 1 and limited, we have to replicate
+ in a nested fashion, sticking OP_BRAZERO before each set of brackets.
+ The first one has to be handled carefully because it's the original
+ copy, which has to be moved up. The remainder can be handled by code
+ that is common with the non-zero minimum case below. We have to
+ adjust the value or repeat_max, since one less copy is required. Once
+ again, we may have to adjust any OP_RECURSE calls inside the group. */
+
+ else
+ {
+ int offset;
+ *code = OP_END;
+ adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
+ code += 2 + LINK_SIZE;
+ *previous++ = OP_BRAZERO + repeat_type;
+ *previous++ = OP_BRA;
+
+ /* We chain together the bracket offset fields that have to be
+ filled in later when the ends of the brackets are reached. */
+
+ offset = (bralink == NULL)? 0 : (int)(previous - bralink);
+ bralink = previous;
+ PUTINC(previous, 0, offset);
+ }
+
+ repeat_max--;
+ }
+
+ /* If the minimum is greater than zero, replicate the group as many
+ times as necessary, and adjust the maximum to the number of subsequent
+ copies that we need. If we set a first char from the group, and didn't
+ set a required char, copy the latter from the former. If there are any
+ forward reference subroutine calls in the group, there will be entries on
+ the workspace list; replicate these with an appropriate increment. */
+
+ else
+ {
+ if (repeat_min > 1)
+ {
+ /* In the pre-compile phase, we don't actually do the replication. We
+ just adjust the length as if we had. Do some paranoid checks for
+ potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+ integer type when available, otherwise double. */
+
+ if (lengthptr != NULL)
+ {
+ int delta = (repeat_min - 1)*length_prevgroup;
+ if ((INT64_OR_DOUBLE)(repeat_min - 1)*
+ (INT64_OR_DOUBLE)length_prevgroup >
+ (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real. If there is a set first byte for
+ the group, and we have not yet set a "required byte", set it. Make
+ sure there is enough workspace for copying forward references before
+ doing the copy. */
+
+ else
+ {
+ if (groupsetfirstchar && reqchar < 0) reqchar = firstchar;
+
+ for (i = 1; i < repeat_min; i++)
+ {
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
+ memcpy(code, previous, IN_UCHARS(len));
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+ for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len);
+ cd->hwm += LINK_SIZE;
+ }
+ save_hwm = this_hwm;
+ code += len;
+ }
+ }
+ }
+
+ if (repeat_max > 0) repeat_max -= repeat_min;
+ }
+
+ /* This code is common to both the zero and non-zero minimum cases. If
+ the maximum is limited, it replicates the group in a nested fashion,
+ remembering the bracket starts on a stack. In the case of a zero minimum,
+ the first one was set up above. In all cases the repeat_max now specifies
+ the number of additional copies needed. Again, we must remember to
+ replicate entries on the forward reference list. */
+
+ if (repeat_max >= 0)
+ {
+ /* In the pre-compile phase, we don't actually do the replication. We
+ just adjust the length as if we had. For each repetition we must add 1
+ to the length for BRAZERO and for all but the last repetition we must
+ add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
+ paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
+ a 64-bit integer type when available, otherwise double. */
+
+ if (lengthptr != NULL && repeat_max > 0)
+ {
+ int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
+ 2 - 2*LINK_SIZE; /* Last one doesn't nest */
+ if ((INT64_OR_DOUBLE)repeat_max *
+ (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
+ > (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real */
+
+ else for (i = repeat_max - 1; i >= 0; i--)
+ {
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
+
+ *code++ = OP_BRAZERO + repeat_type;
+
+ /* All but the final copy start a new nesting, maintaining the
+ chain of brackets outstanding. */
+
+ if (i != 0)
+ {
+ int offset;
+ *code++ = OP_BRA;
+ offset = (bralink == NULL)? 0 : (int)(code - bralink);
+ bralink = code;
+ PUTINC(code, 0, offset);
+ }
+
+ memcpy(code, previous, IN_UCHARS(len));
+
+ /* Ensure there is enough workspace for forward references before
+ copying them. */
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+ for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
+ cd->hwm += LINK_SIZE;
+ }
+ save_hwm = this_hwm;
+ code += len;
+ }
+
+ /* Now chain through the pending brackets, and fill in their length
+ fields (which are holding the chain links pro tem). */
+
+ while (bralink != NULL)
+ {
+ int oldlinkoffset;
+ int offset = (int)(code - bralink + 1);
+ pcre_uchar *bra = code - offset;
+ oldlinkoffset = GET(bra, 1);
+ bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
+ *code++ = OP_KET;
+ PUTINC(code, 0, offset);
+ PUT(bra, 1, offset);
+ }
+ }
+
+ /* If the maximum is unlimited, set a repeater in the final copy. For
+ ONCE brackets, that's all we need to do. However, possessively repeated
+ ONCE brackets can be converted into non-capturing brackets, as the
+ behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
+ deal with possessive ONCEs specially.
+
+ Otherwise, when we are doing the actual compile phase, check to see
+ whether this group is one that could match an empty string. If so,
+ convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
+ that runtime checking can be done. [This check is also applied to ONCE
+ groups at runtime, but in a different way.]
+
+ Then, if the quantifier was possessive and the bracket is not a
+ conditional, we convert the BRA code to the POS form, and the KET code to
+ KETRPOS. (It turns out to be convenient at runtime to detect this kind of
+ subpattern at both the start and at the end.) The use of special opcodes
+ makes it possible to reduce greatly the stack usage in pcre_exec(). If
+ the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+
+ Then, if the minimum number of matches is 1 or 0, cancel the possessive
+ flag so that the default action below, of wrapping everything inside
+ atomic brackets, does not happen. When the minimum is greater than 1,
+ there will be earlier copies of the group, and so we still have to wrap
+ the whole thing. */
+
+ else
+ {
+ pcre_uchar *ketcode = code - 1 - LINK_SIZE;
+ pcre_uchar *bracode = ketcode - GET(ketcode, 1);
+
+ /* Convert possessive ONCE brackets to non-capturing */
+
+ if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
+ possessive_quantifier) *bracode = OP_BRA;
+
+ /* For non-possessive ONCE brackets, all we need to do is to
+ set the KET. */
+
+ if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
+ *ketcode = OP_KETRMAX + repeat_type;
+
+ /* Handle non-ONCE brackets and possessive ONCEs (which have been
+ converted to non-capturing above). */
+
+ else
+ {
+ /* In the compile phase, check for empty string matching. */
+
+ if (lengthptr == NULL)
+ {
+ pcre_uchar *scode = bracode;
+ do
+ {
+ if (could_be_empty_branch(scode, ketcode, utf, cd))
+ {
+ *bracode += OP_SBRA - OP_BRA;
+ break;
+ }
+ scode += GET(scode, 1);
+ }
+ while (*scode == OP_ALT);
+ }
+
+ /* Handle possessive quantifiers. */
+
+ if (possessive_quantifier)
+ {
+ /* For COND brackets, we wrap the whole thing in a possessively
+ repeated non-capturing bracket, because we have not invented POS
+ versions of the COND opcodes. Because we are moving code along, we
+ must ensure that any pending recursive references are updated. */
+
+ if (*bracode == OP_COND || *bracode == OP_SCOND)
+ {
+ int nlen = (int)(code - bracode);
+ *code = OP_END;
+ adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
+ code += 1 + LINK_SIZE;
+ nlen += 1 + LINK_SIZE;
+ *bracode = OP_BRAPOS;
+ *code++ = OP_KETRPOS;
+ PUTINC(code, 0, nlen);
+ PUT(bracode, 1, nlen);
+ }
+
+ /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
+
+ else
+ {
+ *bracode += 1; /* Switch to xxxPOS opcodes */
+ *ketcode = OP_KETRPOS;
+ }
+
+ /* If the minimum is zero, mark it as possessive, then unset the
+ possessive flag when the minimum is 0 or 1. */
+
+ if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
+ if (repeat_min < 2) possessive_quantifier = FALSE;
+ }
+
+ /* Non-possessive quantifier */
+
+ else *ketcode = OP_KETRMAX + repeat_type;
+ }
+ }
+ }
+
+ /* If previous is OP_FAIL, it was generated by an empty class [] in
+ JavaScript mode. The other ways in which OP_FAIL can be generated, that is
+ by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
+ error above. We can just ignore the repeat in JS case. */
+
+ else if (*previous == OP_FAIL) goto END_REPEAT;
+
+ /* Else there's some kind of shambles */
+
+ else
+ {
+ *errorcodeptr = ERR11;
+ goto FAILED;
+ }
+
+ /* If the character following a repeat is '+', or if certain optimization
+ tests above succeeded, possessive_quantifier is TRUE. For some opcodes,
+ there are special alternative opcodes for this case. For anything else, we
+ wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+'
+ notation is just syntactic sugar, taken from Sun's Java package, but the
+ special opcodes can optimize it.
+
+ Some (but not all) possessively repeated subpatterns have already been
+ completely handled in the code just above. For them, possessive_quantifier
+ is always FALSE at this stage.
+
+ Note that the repeated item starts at tempcode, not at previous, which
+ might be the first part of a string whose (former) last char we repeated.
+
+ Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
+ an 'upto' may follow. We skip over an 'exact' item, and then test the
+ length of what remains before proceeding. */
+
+ if (possessive_quantifier)
+ {
+ int len;
+
+ if (*tempcode == OP_TYPEEXACT)
+ tempcode += PRIV(OP_lengths)[*tempcode] +
+ ((tempcode[1 + IMM2_SIZE] == OP_PROP
+ || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+
+ else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
+ {
+ tempcode += PRIV(OP_lengths)[*tempcode];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(tempcode[-1]))
+ tempcode += GET_EXTRALEN(tempcode[-1]);
+#endif
+ }
+
+ len = (int)(code - tempcode);
+ if (len > 0) switch (*tempcode)
+ {
+ case OP_STAR: *tempcode = OP_POSSTAR; break;
+ case OP_PLUS: *tempcode = OP_POSPLUS; break;
+ case OP_QUERY: *tempcode = OP_POSQUERY; break;
+ case OP_UPTO: *tempcode = OP_POSUPTO; break;
+
+ case OP_STARI: *tempcode = OP_POSSTARI; break;
+ case OP_PLUSI: *tempcode = OP_POSPLUSI; break;
+ case OP_QUERYI: *tempcode = OP_POSQUERYI; break;
+ case OP_UPTOI: *tempcode = OP_POSUPTOI; break;
+
+ case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
+ case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
+ case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
+ case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
+
+ case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break;
+ case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break;
+ case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break;
+ case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break;
+
+ case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
+ case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
+ case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
+ case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+
+ /* Because we are moving code along, we must ensure that any
+ pending recursive references are updated. */
+
+ default:
+ *code = OP_END;
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+ code += 1 + LINK_SIZE;
+ len += 1 + LINK_SIZE;
+ tempcode[0] = OP_ONCE;
+ *code++ = OP_KET;
+ PUTINC(code, 0, len);
+ PUT(tempcode, 1, len);
+ break;
+ }
+ }
+
+ /* In all case we no longer have a previous item. We also set the
+ "follows varying string" flag for subsequently encountered reqchars if
+ it isn't already set and we have just passed a varying length item. */
+
+ END_REPEAT:
+ previous = NULL;
+ cd->req_varyopt |= reqvary;
+ break;
+
+
+ /* ===================================================================*/
+ /* Start of nested parenthesized sub-expression, or comment or lookahead or
+ lookbehind or option setting or condition or all the other extended
+ parenthesis forms. */
+
+ case CHAR_LEFT_PARENTHESIS:
+ newoptions = options;
+ skipbytes = 0;
+ bravalue = OP_CBRA;
+ save_hwm = cd->hwm;
+ reset_bracount = FALSE;
+
+ /* First deal with various "verbs" that can be introduced by '*'. */
+
+ ptr++;
+ if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
+ || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
+ {
+ int i, namelen;
+ int arglen = 0;
+ const char *vn = verbnames;
+ const pcre_uchar *name = ptr + 1;
+ const pcre_uchar *arg = NULL;
+ previous = NULL;
+ ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* It appears that Perl allows any characters whatsoever, other than
+ a closing parenthesis, to appear in arguments, so we no longer insist on
+ letters, digits, and underscores. */
+
+ if (*ptr == CHAR_COLON)
+ {
+ arg = ++ptr;
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ arglen = (int)(ptr - arg);
+ }
+
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR60;
+ goto FAILED;
+ }
+
+ /* Scan the table of verb names */
+
+ for (i = 0; i < verbcount; i++)
+ {
+ if (namelen == verbs[i].len &&
+ STRNCMP_UC_C8(name, vn, namelen) == 0)
+ {
+ /* Check for open captures before ACCEPT and convert it to
+ ASSERT_ACCEPT if in an assertion. */
+
+ if (verbs[i].op == OP_ACCEPT)
+ {
+ open_capitem *oc;
+ if (arglen != 0)
+ {
+ *errorcodeptr = ERR59;
+ goto FAILED;
+ }
+ cd->had_accept = TRUE;
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+ {
+ *code++ = OP_CLOSE;
+ PUT2INC(code, 0, oc->number);
+ }
+ *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
+
+ /* Do not set firstchar after *ACCEPT */
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ }
+
+ /* Handle other cases with/without an argument */
+
+ else if (arglen == 0)
+ {
+ if (verbs[i].op < 0) /* Argument is mandatory */
+ {
+ *errorcodeptr = ERR66;
+ goto FAILED;
+ }
+ *code = verbs[i].op;
+ if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN;
+ }
+
+ else
+ {
+ if (verbs[i].op_arg < 0) /* Argument is forbidden */
+ {
+ *errorcodeptr = ERR59;
+ goto FAILED;
+ }
+ *code = verbs[i].op_arg;
+ if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN;
+ *code++ = arglen;
+ memcpy(code, arg, IN_UCHARS(arglen));
+ code += arglen;
+ *code++ = 0;
+ }
+
+ break; /* Found verb, exit loop */
+ }
+
+ vn += verbs[i].len + 1;
+ }
+
+ if (i < verbcount) continue; /* Successfully handled a verb */
+ *errorcodeptr = ERR60; /* Verb not recognized */
+ goto FAILED;
+ }
+
+ /* Deal with the extended parentheses; all are introduced by '?', and the
+ appearance of any of them means that this is not a capturing group. */
+
+ else if (*ptr == CHAR_QUESTION_MARK)
+ {
+ int i, set, unset, namelen;
+ int *optset;
+ const pcre_uchar *name;
+ pcre_uchar *slot;
+
+ switch (*(++ptr))
+ {
+ case CHAR_NUMBER_SIGN: /* Comment; skip to ket */
+ ptr++;
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ if (*ptr == 0)
+ {
+ *errorcodeptr = ERR18;
+ goto FAILED;
+ }
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
+ reset_bracount = TRUE;
+ /* Fall through */
+
+ /* ------------------------------------------------------------ */
+ case CHAR_COLON: /* Non-capturing bracket */
+ bravalue = OP_BRA;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_LEFT_PARENTHESIS:
+ bravalue = OP_COND; /* Conditional group */
+
+ /* A condition can be an assertion, a number (referring to a numbered
+ group), a name (referring to a named group), or 'R', referring to
+ recursion. R<digits> and R&name are also permitted for recursion tests.
+
+ There are several syntaxes for testing a named group: (?(name)) is used
+ by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+
+ There are two unfortunate ambiguities, caused by history. (a) 'R' can
+ be the recursive thing or the name 'R' (and similarly for 'R' followed
+ by digits), and (b) a number could be a name that consists of digits.
+ In both cases, we look for a name first; if not found, we try the other
+ cases. */
+
+ /* For conditions that are assertions, check the syntax, and then exit
+ the switch. This will take control down to where bracketed groups,
+ including assertions, are processed. */
+
+ if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN ||
+ ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN))
+ break;
+
+ /* Most other conditions use OP_CREF (a couple change to OP_RREF
+ below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
+
+ code[1+LINK_SIZE] = OP_CREF;
+ skipbytes = 1+IMM2_SIZE;
+ refsign = -1;
+
+ /* Check for a test for recursion in a named group. */
+
+ if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
+ {
+ terminator = -1;
+ ptr += 2;
+ code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */
+ }
+
+ /* Check for a test for a named group's having been set, using the Perl
+ syntax (?(<name>) or (?('name') */
+
+ else if (ptr[1] == CHAR_LESS_THAN_SIGN)
+ {
+ terminator = CHAR_GREATER_THAN_SIGN;
+ ptr++;
+ }
+ else if (ptr[1] == CHAR_APOSTROPHE)
+ {
+ terminator = CHAR_APOSTROPHE;
+ ptr++;
+ }
+ else
+ {
+ terminator = 0;
+ if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
+ }
+
+ /* We now expect to read a name; any thing else is an error */
+
+ if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
+ {
+ ptr += 1; /* To get the right offset */
+ *errorcodeptr = ERR28;
+ goto FAILED;
+ }
+
+ /* Read the name, but also get it as a number if it's all digits */
+
+ recno = 0;
+ name = ++ptr;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ {
+ if (recno >= 0)
+ recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1;
+ ptr++;
+ }
+ namelen = (int)(ptr - name);
+
+ if ((terminator > 0 && *ptr++ != terminator) ||
+ *ptr++ != CHAR_RIGHT_PARENTHESIS)
+ {
+ ptr--; /* Error offset */
+ *errorcodeptr = ERR26;
+ goto FAILED;
+ }
+
+ /* Do no further checking in the pre-compile phase. */
+
+ if (lengthptr != NULL) break;
+
+ /* In the real compile we do the work of looking for the actual
+ reference. If the string started with "+" or "-" we require the rest to
+ be digits, in which case recno will be set. */
+
+ if (refsign > 0)
+ {
+ if (recno <= 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno = (refsign == CHAR_MINUS)?
+ cd->bracount - recno + 1 : recno +cd->bracount;
+ if (recno <= 0 || recno > cd->final_bracount)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ PUT2(code, 2+LINK_SIZE, recno);
+ break;
+ }
+
+ /* Otherwise (did not start with "+" or "-"), start by looking for the
+ name. If we find a name, add one to the opcode to change OP_CREF or
+ OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
+ except they record that the reference was originally to a name. The
+ information is used to check duplicate names. */
+
+ slot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break;
+ slot += cd->name_entry_size;
+ }
+
+ /* Found a previous named subpattern */
+
+ if (i < cd->names_found)
+ {
+ recno = GET2(slot, 0);
+ PUT2(code, 2+LINK_SIZE, recno);
+ code[1+LINK_SIZE]++;
+ }
+
+ /* Search the pattern for a forward reference */
+
+ else if ((i = find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf)) > 0)
+ {
+ PUT2(code, 2+LINK_SIZE, i);
+ code[1+LINK_SIZE]++;
+ }
+
+ /* If terminator == 0 it means that the name followed directly after
+ the opening parenthesis [e.g. (?(abc)...] and in this case there are
+ some further alternatives to try. For the cases where terminator != 0
+ [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
+ now checked all the possibilities, so give an error. */
+
+ else if (terminator != 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+
+ /* Check for (?(R) for recursion. Allow digits after R to specify a
+ specific group number. */
+
+ else if (*name == CHAR_R)
+ {
+ recno = 0;
+ for (i = 1; i < namelen; i++)
+ {
+ if (!IS_DIGIT(name[i]))
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ recno = recno * 10 + name[i] - CHAR_0;
+ }
+ if (recno == 0) recno = RREF_ANY;
+ code[1+LINK_SIZE] = OP_RREF; /* Change test type */
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
+
+ /* Similarly, check for the (?(DEFINE) "condition", which is always
+ false. */
+
+ else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0)
+ {
+ code[1+LINK_SIZE] = OP_DEF;
+ skipbytes = 1;
+ }
+
+ /* Check for the "name" actually being a subpattern number. We are
+ in the second pass here, so final_bracount is set. */
+
+ else if (recno > 0 && recno <= cd->final_bracount)
+ {
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
+
+ /* Either an unidentified subpattern, or a reference to (?(0) */
+
+ else
+ {
+ *errorcodeptr = (recno == 0)? ERR35: ERR15;
+ goto FAILED;
+ }
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_EQUALS_SIGN: /* Positive lookahead */
+ bravalue = OP_ASSERT;
+ cd->assert_depth += 1;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
+ ptr++;
+ if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
+ {
+ *code++ = OP_FAIL;
+ previous = NULL;
+ continue;
+ }
+ bravalue = OP_ASSERT_NOT;
+ cd->assert_depth += 1;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */
+ switch (ptr[1])
+ {
+ case CHAR_EQUALS_SIGN: /* Positive lookbehind */
+ bravalue = OP_ASSERTBACK;
+ cd->assert_depth += 1;
+ ptr += 2;
+ break;
+
+ case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */
+ bravalue = OP_ASSERTBACK_NOT;
+ cd->assert_depth += 1;
+ ptr += 2;
+ break;
+
+ default: /* Could be name define, else bad */
+ if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
+ goto DEFINE_NAME;
+ ptr++; /* Correct offset for error */
+ *errorcodeptr = ERR24;
+ goto FAILED;
+ }
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_GREATER_THAN_SIGN: /* One-time brackets */
+ bravalue = OP_ONCE;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_C: /* Callout - may be followed by digits; */
+ previous_callout = code; /* Save for later completion */
+ after_manual_callout = 1; /* Skip one item before completing */
+ *code++ = OP_CALLOUT;
+ {
+ int n = 0;
+ ptr++;
+ while(IS_DIGIT(*ptr))
+ n = n * 10 + *ptr++ - CHAR_0;
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR39;
+ goto FAILED;
+ }
+ if (n > 255)
+ {
+ *errorcodeptr = ERR38;
+ goto FAILED;
+ }
+ *code++ = n;
+ PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
+ PUT(code, LINK_SIZE, 0); /* Default length */
+ code += 2 * LINK_SIZE;
+ }
+ previous = NULL;
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_P: /* Python-style named subpattern handling */
+ if (*(++ptr) == CHAR_EQUALS_SIGN ||
+ *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */
+ {
+ is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ goto NAMED_REF_OR_RECURSE;
+ }
+ else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */
+ {
+ *errorcodeptr = ERR41;
+ goto FAILED;
+ }
+ /* Fall through to handle (?P< as (?< is handled */
+
+
+ /* ------------------------------------------------------------ */
+ DEFINE_NAME: /* Come here from (?< handling */
+ case CHAR_APOSTROPHE:
+ {
+ terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+ name = ++ptr;
+
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* In the pre-compile phase, just do a syntax check. */
+
+ if (lengthptr != NULL)
+ {
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ if (cd->names_found >= MAX_NAME_COUNT)
+ {
+ *errorcodeptr = ERR49;
+ goto FAILED;
+ }
+ if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
+ {
+ cd->name_entry_size = namelen + IMM2_SIZE + 1;
+ if (namelen > MAX_NAME_SIZE)
+ {
+ *errorcodeptr = ERR48;
+ goto FAILED;
+ }
+ }
+ }
+
+ /* In the real compile, create the entry in the table, maintaining
+ alphabetical order. Duplicate names for different numbers are
+ permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
+ number are always OK. (An existing number can be re-used if (?|
+ appears in the pattern.) In either event, a duplicate name results in
+ a duplicate entry in the table, even if the number is the same. This
+ is because the number of names, and hence the table size, is computed
+ in the pre-compile, and it affects various numbers and pointers which
+ would all have to be modified, and the compiled code moved down, if
+ duplicates with the same number were omitted from the table. This
+ doesn't seem worth the hassle. However, *different* names for the
+ same number are not permitted. */
+
+ else
+ {
+ BOOL dupname = FALSE;
+ slot = cd->name_table;
+
+ for (i = 0; i < cd->names_found; i++)
+ {
+ int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
+ if (crc == 0)
+ {
+ if (slot[IMM2_SIZE+namelen] == 0)
+ {
+ if (GET2(slot, 0) != cd->bracount + 1 &&
+ (options & PCRE_DUPNAMES) == 0)
+ {
+ *errorcodeptr = ERR43;
+ goto FAILED;
+ }
+ else dupname = TRUE;
+ }
+ else crc = -1; /* Current name is a substring */
+ }
+
+ /* Make space in the table and break the loop for an earlier
+ name. For a duplicate or later name, carry on. We do this for
+ duplicates so that in the simple case (when ?(| is not used) they
+ are in order of their numbers. */
+
+ if (crc < 0)
+ {
+ memmove(slot + cd->name_entry_size, slot,
+ IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
+ break;
+ }
+
+ /* Continue the loop for a later or duplicate name */
+
+ slot += cd->name_entry_size;
+ }
+
+ /* For non-duplicate names, check for a duplicate number before
+ adding the new name. */
+
+ if (!dupname)
+ {
+ pcre_uchar *cslot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (cslot != slot)
+ {
+ if (GET2(cslot, 0) == cd->bracount + 1)
+ {
+ *errorcodeptr = ERR65;
+ goto FAILED;
+ }
+ }
+ else i--;
+ cslot += cd->name_entry_size;
+ }
+ }
+
+ PUT2(slot, 0, cd->bracount + 1);
+ memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
+ slot[IMM2_SIZE + namelen] = 0;
+ }
+ }
+
+ /* In both pre-compile and compile, count the number of names we've
+ encountered. */
+
+ cd->names_found++;
+ ptr++; /* Move past > or ' */
+ goto NUMBERED_GROUP;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ is_recurse = TRUE;
+ /* Fall through */
+
+ /* We come here from the Python syntax above that handles both
+ references (?P=name) and recursion (?P>name), as well as falling
+ through from the Perl recursion syntax (?&name). We also come here from
+ the Perl \k<name> or \k'name' back reference syntax and the \k{name}
+ .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
+
+ NAMED_REF_OR_RECURSE:
+ name = ++ptr;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* In the pre-compile phase, do a syntax check. We used to just set
+ a dummy reference number, because it was not used in the first pass.
+ However, with the change of recursive back references to be atomic,
+ we have to look for the number so that this state can be identified, as
+ otherwise the incorrect length is computed. If it's not a backwards
+ reference, the dummy number will do. */
+
+ if (lengthptr != NULL)
+ {
+ const pcre_uchar *temp;
+
+ if (namelen == 0)
+ {
+ *errorcodeptr = ERR62;
+ goto FAILED;
+ }
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ if (namelen > MAX_NAME_SIZE)
+ {
+ *errorcodeptr = ERR48;
+ goto FAILED;
+ }
+
+ /* The name table does not exist in the first pass, so we cannot
+ do a simple search as in the code below. Instead, we have to scan the
+ pattern to find the number. It is important that we scan it only as
+ far as we have got because the syntax of named subpatterns has not
+ been checked for the rest of the pattern, and find_parens() assumes
+ correct syntax. In any case, it's a waste of resources to scan
+ further. We stop the scan at the current point by temporarily
+ adjusting the value of cd->endpattern. */
+
+ temp = cd->end_pattern;
+ cd->end_pattern = ptr;
+ recno = find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf);
+ cd->end_pattern = temp;
+ if (recno < 0) recno = 0; /* Forward ref; set dummy number */
+ }
+
+ /* In the real compile, seek the name in the table. We check the name
+ first, and then check that we have reached the end of the name in the
+ table. That way, if the name that is longer than any in the table,
+ the comparison will fail without reading beyond the table entry. */
+
+ else
+ {
+ slot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 &&
+ slot[IMM2_SIZE+namelen] == 0)
+ break;
+ slot += cd->name_entry_size;
+ }
+
+ if (i < cd->names_found) /* Back reference */
+ {
+ recno = GET2(slot, 0);
+ }
+ else if ((recno = /* Forward back reference */
+ find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf)) <= 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ }
+
+ /* In both phases, we can now go to the code than handles numerical
+ recursion or backreferences. */
+
+ if (is_recurse) goto HANDLE_RECURSION;
+ else goto HANDLE_REFERENCE;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_R: /* Recursion */
+ ptr++; /* Same as (?0) */
+ /* Fall through */
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */
+ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
+ case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+ {
+ const pcre_uchar *called;
+ terminator = CHAR_RIGHT_PARENTHESIS;
+
+ /* Come here from the \g<...> and \g'...' code (Oniguruma
+ compatibility). However, the syntax has been checked to ensure that
+ the ... are a (signed) number, so that neither ERR63 nor ERR29 will
+ be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
+ ever be taken. */
+
+ HANDLE_NUMERICAL_RECURSION:
+
+ if ((refsign = *ptr) == CHAR_PLUS)
+ {
+ ptr++;
+ if (!IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR63;
+ goto FAILED;
+ }
+ }
+ else if (refsign == CHAR_MINUS)
+ {
+ if (!IS_DIGIT(ptr[1]))
+ goto OTHER_CHAR_AFTER_QUERY;
+ ptr++;
+ }
+
+ recno = 0;
+ while(IS_DIGIT(*ptr))
+ recno = recno * 10 + *ptr++ - CHAR_0;
+
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR29;
+ goto FAILED;
+ }
+
+ if (refsign == CHAR_MINUS)
+ {
+ if (recno == 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno = cd->bracount - recno + 1;
+ if (recno <= 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ }
+ else if (refsign == CHAR_PLUS)
+ {
+ if (recno == 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno += cd->bracount;
+ }
+
+ /* Come here from code above that handles a named recursion */
+
+ HANDLE_RECURSION:
+
+ previous = code;
+ called = cd->start_code;
+
+ /* When we are actually compiling, find the bracket that is being
+ referenced. Temporarily end the regex in case it doesn't exist before
+ this point. If we end up with a forward reference, first check that
+ the bracket does occur later so we can give the error (and position)
+ now. Then remember this forward reference in the workspace so it can
+ be filled in at the end. */
+
+ if (lengthptr == NULL)
+ {
+ *code = OP_END;
+ if (recno != 0)
+ called = PRIV(find_bracket)(cd->start_code, utf, recno);
+
+ /* Forward reference */
+
+ if (called == NULL)
+ {
+ if (find_parens(cd, NULL, recno,
+ (options & PCRE_EXTENDED) != 0, utf) < 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+
+ /* Fudge the value of "called" so that when it is inserted as an
+ offset below, what it actually inserted is the reference number
+ of the group. Then remember the forward reference. */
+
+ called = cd->start_code + recno;
+ if (cd->hwm >= cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
+ {
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ }
+ PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
+ }
+
+ /* If not a forward reference, and the subpattern is still open,
+ this is a recursive call. We check to see if this is a left
+ recursion that could loop for ever, and diagnose that case. We
+ must not, however, do this check if we are in a conditional
+ subpattern because the condition might be testing for recursion in
+ a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid.
+ Forever loops are also detected at runtime, so those that occur in
+ conditional subpatterns will be picked up then. */
+
+ else if (GET(called, 1) == 0 && cond_depth <= 0 &&
+ could_be_empty(called, code, bcptr, utf, cd))
+ {
+ *errorcodeptr = ERR40;
+ goto FAILED;
+ }
+ }
+
+ /* Insert the recursion/subroutine item. It does not have a set first
+ character (relevant if it is repeated, because it will then be
+ wrapped with ONCE brackets). */
+
+ *code = OP_RECURSE;
+ PUT(code, 1, (int)(called - cd->start_code));
+ code += 1 + LINK_SIZE;
+ groupsetfirstchar = FALSE;
+ }
+
+ /* Can't determine a first byte now */
+
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ default: /* Other characters: check option setting */
+ OTHER_CHAR_AFTER_QUERY:
+ set = unset = 0;
+ optset = &set;
+
+ while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
+ {
+ switch (*ptr++)
+ {
+ case CHAR_MINUS: optset = &unset; break;
+
+ case CHAR_J: /* Record that it changed in the external options */
+ *optset |= PCRE_DUPNAMES;
+ cd->external_flags |= PCRE_JCHANGED;
+ break;
+
+ case CHAR_i: *optset |= PCRE_CASELESS; break;
+ case CHAR_m: *optset |= PCRE_MULTILINE; break;
+ case CHAR_s: *optset |= PCRE_DOTALL; break;
+ case CHAR_x: *optset |= PCRE_EXTENDED; break;
+ case CHAR_U: *optset |= PCRE_UNGREEDY; break;
+ case CHAR_X: *optset |= PCRE_EXTRA; break;
+
+ default: *errorcodeptr = ERR12;
+ ptr--; /* Correct the offset */
+ goto FAILED;
+ }
+ }
+
+ /* Set up the changed option bits, but don't change anything yet. */
+
+ newoptions = (options | set) & (~unset);
+
+ /* If the options ended with ')' this is not the start of a nested
+ group with option changes, so the options change at this level. If this
+ item is right at the start of the pattern, the options can be
+ abstracted and made external in the pre-compile phase, and ignored in
+ the compile phase. This can be helpful when matching -- for instance in
+ caseless checking of required bytes.
+
+ If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
+ definitely *not* at the start of the pattern because something has been
+ compiled. In the pre-compile phase, however, the code pointer can have
+ that value after the start, because it gets reset as code is discarded
+ during the pre-compile. However, this can happen only at top level - if
+ we are within parentheses, the starting BRA will still be present. At
+ any parenthesis level, the length value can be used to test if anything
+ has been compiled at that level. Thus, a test for both these conditions
+ is necessary to ensure we correctly detect the start of the pattern in
+ both phases.
+
+ If we are not at the pattern start, reset the greedy defaults and the
+ case value for firstchar and reqchar. */
+
+ if (*ptr == CHAR_RIGHT_PARENTHESIS)
+ {
+ if (code == cd->start_code + 1 + LINK_SIZE &&
+ (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
+ {
+ cd->external_options = newoptions;
+ }
+ else
+ {
+ greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
+ greedy_non_default = greedy_default ^ 1;
+ req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
+ }
+
+ /* Change options at this level, and pass them back for use
+ in subsequent branches. */
+
+ *optionsptr = options = newoptions;
+ previous = NULL; /* This item can't be repeated */
+ continue; /* It is complete */
+ }
+
+ /* If the options ended with ':' we are heading into a nested group
+ with possible change of options. Such groups are non-capturing and are
+ not assertions of any kind. All we need to do is skip over the ':';
+ the newoptions value is handled below. */
+
+ bravalue = OP_BRA;
+ ptr++;
+ } /* End of switch for character following (? */
+ } /* End of (? handling */
+
+ /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE
+ is set, all unadorned brackets become non-capturing and behave like (?:...)
+ brackets. */
+
+ else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
+ {
+ bravalue = OP_BRA;
+ }
+
+ /* Else we have a capturing group. */
+
+ else
+ {
+ NUMBERED_GROUP:
+ cd->bracount += 1;
+ PUT2(code, 1+LINK_SIZE, cd->bracount);
+ skipbytes = IMM2_SIZE;
+ }
+
+ /* Process nested bracketed regex. Assertions used not to be repeatable,
+ but this was changed for Perl compatibility, so all kinds can now be
+ repeated. We copy code into a non-register variable (tempcode) in order to
+ be able to pass its address because some compilers complain otherwise. */
+
+ previous = code; /* For handling repetition */
+ *code = bravalue;
+ tempcode = code;
+ tempreqvary = cd->req_varyopt; /* Save value before bracket */
+ tempbracount = cd->bracount; /* Save value before bracket */
+ length_prevgroup = 0; /* Initialize for pre-compile phase */
+
+ if (!compile_regex(
+ newoptions, /* The complete new option state */
+ &tempcode, /* Where to put code (updated) */
+ &ptr, /* Input pointer (updated) */
+ errorcodeptr, /* Where to put an error message */
+ (bravalue == OP_ASSERTBACK ||
+ bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
+ reset_bracount, /* True if (?| group */
+ skipbytes, /* Skip over bracket number */
+ cond_depth +
+ ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */
+ &subfirstchar, /* For possible first char */
+ &subreqchar, /* For possible last char */
+ bcptr, /* Current branch chain */
+ cd, /* Tables block */
+ (lengthptr == NULL)? NULL : /* Actual compile phase */
+ &length_prevgroup /* Pre-compile phase */
+ ))
+ goto FAILED;
+
+ /* If this was an atomic group and there are no capturing groups within it,
+ generate OP_ONCE_NC instead of OP_ONCE. */
+
+ if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
+ *code = OP_ONCE_NC;
+
+ if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+ cd->assert_depth -= 1;
+
+ /* At the end of compiling, code is still pointing to the start of the
+ group, while tempcode has been updated to point past the end of the group.
+ The pattern pointer (ptr) is on the bracket.
+
+ If this is a conditional bracket, check that there are no more than
+ two branches in the group, or just one if it's a DEFINE group. We do this
+ in the real compile phase, not in the pre-pass, where the whole group may
+ not be available. */
+
+ if (bravalue == OP_COND && lengthptr == NULL)
+ {
+ pcre_uchar *tc = code;
+ int condcount = 0;
+
+ do {
+ condcount++;
+ tc += GET(tc,1);
+ }
+ while (*tc != OP_KET);
+
+ /* A DEFINE group is never obeyed inline (the "condition" is always
+ false). It must have only one branch. */
+
+ if (code[LINK_SIZE+1] == OP_DEF)
+ {
+ if (condcount > 1)
+ {
+ *errorcodeptr = ERR54;
+ goto FAILED;
+ }
+ bravalue = OP_DEF; /* Just a flag to suppress char handling below */
+ }
+
+ /* A "normal" conditional group. If there is just one branch, we must not
+ make use of its firstchar or reqchar, because this is equivalent to an
+ empty second branch. */
+
+ else
+ {
+ if (condcount > 2)
+ {
+ *errorcodeptr = ERR27;
+ goto FAILED;
+ }
+ if (condcount == 1) subfirstchar = subreqchar = REQ_NONE;
+ }
+ }
+
+ /* Error if hit end of pattern */
+
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR14;
+ goto FAILED;
+ }
+
+ /* In the pre-compile phase, update the length by the length of the group,
+ less the brackets at either end. Then reduce the compiled code to just a
+ set of non-capturing brackets so that it doesn't use much memory if it is
+ duplicated by a quantifier.*/
+
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
+ code++; /* This already contains bravalue */
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ *code++ = OP_KET;
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ break; /* No need to waste time with special character handling */
+ }
+
+ /* Otherwise update the main code pointer to the end of the group. */
+
+ code = tempcode;
+
+ /* For a DEFINE group, required and first character settings are not
+ relevant. */
+
+ if (bravalue == OP_DEF) break;
+
+ /* Handle updating of the required and first characters for other types of
+ group. Update for normal brackets of all kinds, and conditions with two
+ branches (see code above). If the bracket is followed by a quantifier with
+ zero repeat, we have to back off. Hence the definition of zeroreqchar and
+ zerofirstchar outside the main loop so that they can be accessed for the
+ back off. */
+
+ zeroreqchar = reqchar;
+ zerofirstchar = firstchar;
+ groupsetfirstchar = FALSE;
+
+ if (bravalue >= OP_ONCE)
+ {
+ /* If we have not yet set a firstchar in this branch, take it from the
+ subpattern, remembering that it was set here so that a repeat of more
+ than one can replicate it as reqchar if necessary. If the subpattern has
+ no firstchar, set "none" for the whole branch. In both cases, a zero
+ repeat forces firstchar to "none". */
+
+ if (firstchar == REQ_UNSET)
+ {
+ if (subfirstchar >= 0)
+ {
+ firstchar = subfirstchar;
+ groupsetfirstchar = TRUE;
+ }
+ else firstchar = REQ_NONE;
+ zerofirstchar = REQ_NONE;
+ }
+
+ /* If firstchar was previously set, convert the subpattern's firstchar
+ into reqchar if there wasn't one, using the vary flag that was in
+ existence beforehand. */
+
+ else if (subfirstchar >= 0 && subreqchar < 0)
+ subreqchar = subfirstchar | tempreqvary;
+
+ /* If the subpattern set a required byte (or set a first byte that isn't
+ really the first byte - see above), set it. */
+
+ if (subreqchar >= 0) reqchar = subreqchar;
+ }
+
+ /* For a forward assertion, we take the reqchar, if set. This can be
+ helpful if the pattern that follows the assertion doesn't set a different
+ char. For example, it's useful for /(?=abcde).+/. We can't set firstchar
+ for an assertion, however because it leads to incorrect effect for patterns
+ such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead
+ of a firstchar. This is overcome by a scan at the end if there's no
+ firstchar, looking for an asserted first char. */
+
+ else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar;
+ break; /* End of processing '(' */
+
+
+ /* ===================================================================*/
+ /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
+ are arranged to be the negation of the corresponding OP_values in the
+ default case when PCRE_UCP is not set. For the back references, the values
+ are ESC_REF plus the reference number. Only back references and those types
+ that consume a character may be repeated. We can test for values between
+ ESC_b and ESC_Z for the latter; this may have to change if any new ones are
+ ever created. */
+
+ case CHAR_BACKSLASH:
+ tempptr = ptr;
+ c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ if (c < 0)
+ {
+ if (-c == ESC_Q) /* Handle start of quoted string */
+ {
+ if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ ptr += 2; /* avoid empty string */
+ else inescq = TRUE;
+ continue;
+ }
+
+ if (-c == ESC_E) continue; /* Perl ignores an orphan \E */
+
+ /* For metasequences that actually match a character, we disable the
+ setting of a first character if it hasn't already been set. */
+
+ if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
+ firstchar = REQ_NONE;
+
+ /* Set values to reset to if this is followed by a zero repeat. */
+
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+
+ /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
+ is a subroutine call by number (Oniguruma syntax). In fact, the value
+ -ESC_g is returned only for these cases. So we don't need to check for <
+ or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
+ -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
+ that is a synonym for a named back reference). */
+
+ if (-c == ESC_g)
+ {
+ const pcre_uchar *p;
+ save_hwm = cd->hwm; /* Normally this is set when '(' is read */
+ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+
+ /* These two statements stop the compiler for warning about possibly
+ unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
+ fact, because we actually check for a number below, the paths that
+ would actually be in error are never taken. */
+
+ skipbytes = 0;
+ reset_bracount = FALSE;
+
+ /* Test for a name */
+
+ if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
+ {
+ BOOL is_a_number = TRUE;
+ for (p = ptr + 1; *p != 0 && *p != terminator; p++)
+ {
+ if (!MAX_255(*p)) { is_a_number = FALSE; break; }
+ if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;
+ if ((cd->ctypes[*p] & ctype_word) == 0) break;
+ }
+ if (*p != terminator)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+ if (is_a_number)
+ {
+ ptr++;
+ goto HANDLE_NUMERICAL_RECURSION;
+ }
+ is_recurse = TRUE;
+ goto NAMED_REF_OR_RECURSE;
+ }
+
+ /* Test a signed number in angle brackets or quotes. */
+
+ p = ptr + 2;
+ while (IS_DIGIT(*p)) p++;
+ if (*p != terminator)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+ ptr++;
+ goto HANDLE_NUMERICAL_RECURSION;
+ }
+
+ /* \k<name> or \k'name' is a back reference by name (Perl syntax).
+ We also support \k{name} (.NET syntax). */
+
+ if (-c == ESC_k)
+ {
+ if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
+ ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
+ {
+ *errorcodeptr = ERR69;
+ break;
+ }
+ is_recurse = FALSE;
+ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
+ CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
+ goto NAMED_REF_OR_RECURSE;
+ }
+
+ /* Back references are handled specially; must disable firstchar if
+ not set to cope with cases like (?=(\w+))\1: which would otherwise set
+ ':' later. */
+
+ if (-c >= ESC_REF)
+ {
+ open_capitem *oc;
+ recno = -c - ESC_REF;
+
+ HANDLE_REFERENCE: /* Come here from named backref handling */
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
+ PUT2INC(code, 0, recno);
+ cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+ if (recno > cd->top_backref) cd->top_backref = recno;
+
+ /* Check to see if this back reference is recursive, that it, it
+ is inside the group that it references. A flag is set so that the
+ group can be made atomic. */
+
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (oc->number == recno)
+ {
+ oc->flag = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* So are Unicode property matches, if supported. */
+
+#ifdef SUPPORT_UCP
+ else if (-c == ESC_P || -c == ESC_p)
+ {
+ BOOL negated;
+ int pdata;
+ int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+ if (ptype < 0) goto FAILED;
+ previous = code;
+ *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
+ *code++ = ptype;
+ *code++ = pdata;
+ }
+#else
+
+ /* If Unicode properties are not supported, \X, \P, and \p are not
+ allowed. */
+
+ else if (-c == ESC_X || -c == ESC_P || -c == ESC_p)
+ {
+ *errorcodeptr = ERR45;
+ goto FAILED;
+ }
+#endif
+
+ /* For the rest (including \X when Unicode properties are supported), we
+ can obtain the OP value by negating the escape value in the default
+ situation when PCRE_UCP is not set. When it *is* set, we substitute
+ Unicode property tests. */
+
+ else
+ {
+#ifdef SUPPORT_UCP
+ if (-c >= ESC_DU && -c <= ESC_wu)
+ {
+ nestptr = ptr + 1; /* Where to resume */
+ ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
+ }
+ else
+#endif
+ /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
+ so that it works in DFA mode and in lookbehinds. */
+
+ {
+ previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
+ *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c;
+ }
+ }
+ continue;
+ }
+
+ /* We have a data character whose value is in c. In UTF-8 mode it may have
+ a value > 127. We set its representation in the length/buffer, and then
+ handle it as a data character. */
+
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
+ else
+#endif
+
+ {
+ mcbuffer[0] = c;
+ mclength = 1;
+ }
+ goto ONE_CHAR;
+
+
+ /* ===================================================================*/
+ /* Handle a literal character. It is guaranteed not to be whitespace or #
+ when the extended flag is set. If we are in UTF-8 mode, it may be a
+ multi-byte literal character. */
+
+ default:
+ NORMAL_CHAR:
+ mclength = 1;
+ mcbuffer[0] = c;
+
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
+ ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
+#endif
+
+ /* At this point we have the character's bytes in mcbuffer, and the length
+ in mclength. When not in UTF-8 mode, the length is always 1. */
+
+ ONE_CHAR:
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR;
+ for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
+
+ /* Remember if \r or \n were seen */
+
+ if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
+ cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Set the first and required bytes appropriately. If no previous first
+ byte, set it from this character, but revert to none on a zero repeat.
+ Otherwise, leave the firstchar value alone, and don't change it on a zero
+ repeat. */
+
+ if (firstchar == REQ_UNSET)
+ {
+ zerofirstchar = REQ_NONE;
+ zeroreqchar = reqchar;
+
+ /* If the character is more than one byte long, we can set firstchar
+ only if it is not to be matched caselessly. */
+
+ if (mclength == 1 || req_caseopt == 0)
+ {
+ firstchar = mcbuffer[0] | req_caseopt;
+ if (mclength != 1) reqchar = code[-1] | cd->req_varyopt;
+ }
+ else firstchar = reqchar = REQ_NONE;
+ }
+
+ /* firstchar was previously set; we can set reqchar only if the length is
+ 1 or the matching is caseful. */
+
+ else
+ {
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+ if (mclength == 1 || req_caseopt == 0)
+ reqchar = code[-1] | req_caseopt | cd->req_varyopt;
+ }
+
+ break; /* End of literal character handling */
+ }
+ } /* end of big loop */
+
+
+/* Control never reaches here by falling through, only by a goto for all the
+error states. Pass back the position in the pattern so that it can be displayed
+to the user for diagnosing the error. */
+
+FAILED:
+*ptrptr = ptr;
+return FALSE;
+}
+
+
+
+
+/*************************************************
+* Compile sequence of alternatives *
+*************************************************/
+
+/* On entry, ptr is pointing past the bracket character, but on return it
+points to the closing bracket, or vertical bar, or end of string. The code
+variable is pointing at the byte into which the BRA operator has been stored.
+This function is used during the pre-compile phase when we are trying to find
+out the amount of memory needed, as well as during the real compile phase. The
+value of lengthptr distinguishes the two phases.
+
+Arguments:
+ options option bits, including any changes for this subpattern
+ codeptr -> the address of the current code pointer
+ ptrptr -> the address of the current pattern pointer
+ errorcodeptr -> pointer to error code variable
+ lookbehind TRUE if this is a lookbehind assertion
+ reset_bracount TRUE to reset the count for each branch
+ skipbytes skip this many bytes at start (for brackets and OP_COND)
+ cond_depth depth of nesting for conditional subpatterns
+ firstcharptr place to put the first required character, or a negative number
+ reqcharptr place to put the last required character, or a negative number
+ bcptr pointer to the chain of currently open branches
+ cd points to the data block with tables pointers etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE on success
+*/
+
+static BOOL
+compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr,
+ int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
+ int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr,
+ branch_chain *bcptr, compile_data *cd, int *lengthptr)
+{
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar *code = *codeptr;
+pcre_uchar *last_branch = code;
+pcre_uchar *start_bracket = code;
+pcre_uchar *reverse_count = NULL;
+open_capitem capitem;
+int capnumber = 0;
+pcre_int32 firstchar, reqchar;
+pcre_int32 branchfirstchar, branchreqchar;
+int length;
+int orig_bracount;
+int max_bracount;
+branch_chain bc;
+
+bc.outer = bcptr;
+bc.current_branch = code;
+
+firstchar = reqchar = REQ_UNSET;
+
+/* Accumulate the length for use in the pre-compile phase. Start with the
+length of the BRA and KET and any extra bytes that are required at the
+beginning. We accumulate in a local variable to save frequent testing of
+lenthptr for NULL. We cannot do this by looking at the value of code at the
+start and end of each alternative, because compiled items are discarded during
+the pre-compile phase so that the work space is not exceeded. */
+
+length = 2 + 2*LINK_SIZE + skipbytes;
+
+/* WARNING: If the above line is changed for any reason, you must also change
+the code that abstracts option settings at the start of the pattern and makes
+them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
+pre-compile phase to find out whether anything has yet been compiled or not. */
+
+/* If this is a capturing subpattern, add to the chain of open capturing items
+so that we can detect them if (*ACCEPT) is encountered. This is also used to
+detect groups that contain recursive back references to themselves. Note that
+only OP_CBRA need be tested here; changing this opcode to one of its variants,
+e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
+
+if (*code == OP_CBRA)
+ {
+ capnumber = GET2(code, 1 + LINK_SIZE);
+ capitem.number = capnumber;
+ capitem.next = cd->open_caps;
+ capitem.flag = FALSE;
+ cd->open_caps = &capitem;
+ }
+
+/* Offset is set zero to mark that this bracket is still open */
+
+PUT(code, 1, 0);
+code += 1 + LINK_SIZE + skipbytes;
+
+/* Loop for each alternative branch */
+
+orig_bracount = max_bracount = cd->bracount;
+for (;;)
+ {
+ /* For a (?| group, reset the capturing bracket count so that each branch
+ uses the same numbers. */
+
+ if (reset_bracount) cd->bracount = orig_bracount;
+
+ /* Set up dummy OP_REVERSE if lookbehind assertion */
+
+ if (lookbehind)
+ {
+ *code++ = OP_REVERSE;
+ reverse_count = code;
+ PUTINC(code, 0, 0);
+ length += 1 + LINK_SIZE;
+ }
+
+ /* Now compile the branch; in the pre-compile phase its length gets added
+ into the length. */
+
+ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar,
+ &branchreqchar, &bc, cond_depth, cd,
+ (lengthptr == NULL)? NULL : &length))
+ {
+ *ptrptr = ptr;
+ return FALSE;
+ }
+
+ /* Keep the highest bracket count in case (?| was used and some branch
+ has fewer than the rest. */
+
+ if (cd->bracount > max_bracount) max_bracount = cd->bracount;
+
+ /* In the real compile phase, there is some post-processing to be done. */
+
+ if (lengthptr == NULL)
+ {
+ /* If this is the first branch, the firstchar and reqchar values for the
+ branch become the values for the regex. */
+
+ if (*last_branch != OP_ALT)
+ {
+ firstchar = branchfirstchar;
+ reqchar = branchreqchar;
+ }
+
+ /* If this is not the first branch, the first char and reqchar have to
+ match the values from all the previous branches, except that if the
+ previous value for reqchar didn't have REQ_VARY set, it can still match,
+ and we set REQ_VARY for the regex. */
+
+ else
+ {
+ /* If we previously had a firstchar, but it doesn't match the new branch,
+ we have to abandon the firstchar for the regex, but if there was
+ previously no reqchar, it takes on the value of the old firstchar. */
+
+ if (firstchar >= 0 && firstchar != branchfirstchar)
+ {
+ if (reqchar < 0) reqchar = firstchar;
+ firstchar = REQ_NONE;
+ }
+
+ /* If we (now or from before) have no firstchar, a firstchar from the
+ branch becomes a reqchar if there isn't a branch reqchar. */
+
+ if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0)
+ branchreqchar = branchfirstchar;
+
+ /* Now ensure that the reqchars match */
+
+ if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY))
+ reqchar = REQ_NONE;
+ else reqchar |= branchreqchar; /* To "or" REQ_VARY */
+ }
+
+ /* If lookbehind, check that this branch matches a fixed-length string, and
+ put the length into the OP_REVERSE item. Temporarily mark the end of the
+ branch with OP_END. If the branch contains OP_RECURSE, the result is -3
+ because there may be forward references that we can't check here. Set a
+ flag to cause another lookbehind check at the end. Why not do it all at the
+ end? Because common, erroneous checks are picked up here and the offset of
+ the problem can be shown. */
+
+ if (lookbehind)
+ {
+ int fixed_length;
+ *code = OP_END;
+ fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
+ FALSE, cd);
+ DPRINTF(("fixed length = %d\n", fixed_length));
+ if (fixed_length == -3)
+ {
+ cd->check_lookbehind = TRUE;
+ }
+ else if (fixed_length < 0)
+ {
+ *errorcodeptr = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70: ERR25;
+ *ptrptr = ptr;
+ return FALSE;
+ }
+ else { PUT(reverse_count, 0, fixed_length); }
+ }
+ }
+
+ /* Reached end of expression, either ')' or end of pattern. In the real
+ compile phase, go back through the alternative branches and reverse the chain
+ of offsets, with the field in the BRA item now becoming an offset to the
+ first alternative. If there are no alternatives, it points to the end of the
+ group. The length in the terminating ket is always the length of the whole
+ bracketed item. Return leaving the pointer at the terminating char. */
+
+ if (*ptr != CHAR_VERTICAL_LINE)
+ {
+ if (lengthptr == NULL)
+ {
+ int branch_length = (int)(code - last_branch);
+ do
+ {
+ int prev_length = GET(last_branch, 1);
+ PUT(last_branch, 1, branch_length);
+ branch_length = prev_length;
+ last_branch -= branch_length;
+ }
+ while (branch_length > 0);
+ }
+
+ /* Fill in the ket */
+
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+
+ /* If it was a capturing subpattern, check to see if it contained any
+ recursive back references. If so, we must wrap it in atomic brackets.
+ In any event, remove the block from the chain. */
+
+ if (capnumber > 0)
+ {
+ if (cd->open_caps->flag)
+ {
+ memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+ IN_UCHARS(code - start_bracket));
+ *start_bracket = OP_ONCE;
+ code += 1 + LINK_SIZE;
+ PUT(start_bracket, 1, (int)(code - start_bracket));
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+ length += 2 + 2*LINK_SIZE;
+ }
+ cd->open_caps = cd->open_caps->next;
+ }
+
+ /* Retain the highest bracket number, in case resetting was used. */
+
+ cd->bracount = max_bracount;
+
+ /* Set values to pass back */
+
+ *codeptr = code;
+ *ptrptr = ptr;
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length)
+ {
+ *errorcodeptr = ERR20;
+ return FALSE;
+ }
+ *lengthptr += length;
+ }
+ return TRUE;
+ }
+
+ /* Another branch follows. In the pre-compile phase, we can move the code
+ pointer back to where it was for the start of the first branch. (That is,
+ pretend that each branch is the only one.)
+
+ In the real compile phase, insert an ALT node. Its length field points back
+ to the previous branch while the bracket remains open. At the end the chain
+ is reversed. It's done like this so that the start of the bracket has a
+ zero offset until it is closed, making it possible to detect recursion. */
+
+ if (lengthptr != NULL)
+ {
+ code = *codeptr + 1 + LINK_SIZE + skipbytes;
+ length += 1 + LINK_SIZE;
+ }
+ else
+ {
+ *code = OP_ALT;
+ PUT(code, 1, (int)(code - last_branch));
+ bc.current_branch = last_branch = code;
+ code += 1 + LINK_SIZE;
+ }
+
+ ptr++;
+ }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+* Check for anchored expression *
+*************************************************/
+
+/* Try to find out if this is an anchored regular expression. Consider each
+alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
+all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
+it's anchored. However, if this is a multiline pattern, then only OP_SOD will
+be found, because ^ generates OP_CIRCM in that mode.
+
+We can also consider a regex to be anchored if OP_SOM starts all its branches.
+This is the code for \G, which means "match at start of match position, taking
+into account the match offset".
+
+A branch is also implicitly anchored if it starts with .* and DOTALL is set,
+because that will try the rest of the pattern at all possible matching points,
+so there is no point trying again.... er ....
+
+.... except when the .* appears inside capturing parentheses, and there is a
+subsequent back reference to those parentheses. We haven't enough information
+to catch that case precisely.
+
+At first, the best we could do was to detect when .* was in capturing brackets
+and the highest back reference was greater than or equal to that level.
+However, by keeping a bitmap of the first 31 back references, we can catch some
+of the more common cases more precisely.
+
+Arguments:
+ code points to start of expression (the bracket)
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ backref_map the back reference bitmap
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_anchored(register const pcre_uchar *code, unsigned int bracket_map,
+ unsigned int backref_map)
+{
+do {
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ register int op = *scode;
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ if (!is_anchored(scode, new_map, backref_map)) return FALSE;
+ }
+
+ /* Other brackets */
+
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC ||
+ op == OP_COND)
+ {
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
+ it isn't in brackets that are or may be referenced. */
+
+ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
+ op == OP_TYPEPOSSTAR))
+ {
+ if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
+ return FALSE;
+ }
+
+ /* Check for explicit anchoring */
+
+ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for starting with ^ or .* *
+*************************************************/
+
+/* This is called to find out if every branch starts with ^ or .* so that
+"first char" processing can be done to speed things up in multiline
+matching and for non-DOTALL patterns that start with .* (which must start at
+the beginning or after \n). As in the case of is_anchored() (see above), we
+have to take account of back references to capturing brackets that contain .*
+because in that case we can't make the assumption.
+
+Arguments:
+ code points to start of expression (the bracket)
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ backref_map the back reference bitmap
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_startline(const pcre_uchar *code, unsigned int bracket_map,
+ unsigned int backref_map)
+{
+do {
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ register int op = *scode;
+
+ /* If we are at the start of a conditional assertion group, *both* the
+ conditional assertion *and* what follows the condition must satisfy the test
+ for start of line. Other kinds of condition fail. Note that there may be an
+ auto-callout at the start of a condition. */
+
+ if (op == OP_COND)
+ {
+ scode += 1 + LINK_SIZE;
+ if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
+ switch (*scode)
+ {
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ return FALSE;
+
+ default: /* Assertion */
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ do scode += GET(scode, 1); while (*scode == OP_ALT);
+ scode += 1 + LINK_SIZE;
+ break;
+ }
+ scode = first_significant_code(scode, FALSE);
+ op = *scode;
+ }
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ if (!is_startline(scode, new_map, backref_map)) return FALSE;
+ }
+
+ /* Other brackets */
+
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC)
+ {
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* .* means "start at start or after \n" if it isn't in brackets that
+ may be referenced. */
+
+ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
+ {
+ if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;
+ }
+
+ /* Check for explicit circumflex */
+
+ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
+
+ /* Move on to the next alternative */
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for asserted fixed first char *
+*************************************************/
+
+/* During compilation, the "first char" settings from forward assertions are
+discarded, because they can cause conflicts with actual literals that follow.
+However, if we end up without a first char setting for an unanchored pattern,
+it is worth scanning the regex to see if there is an initial asserted first
+char. If all branches start with the same asserted char, or with a bracket all
+of whose alternatives start with the same asserted char (recurse ad lib), then
+we return that char, otherwise -1.
+
+Arguments:
+ code points to start of expression (the bracket)
+ inassert TRUE if in an assertion
+
+Returns: -1 or the fixed first char
+*/
+
+static int
+find_firstassertedchar(const pcre_uchar *code, BOOL inassert)
+{
+register int c = -1;
+do {
+ int d;
+ int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
+ const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl,
+ TRUE);
+ register int op = *scode;
+
+ switch(op)
+ {
+ default:
+ return -1;
+
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ASSERT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0)
+ return -1;
+ if (c < 0) c = d; else if (c != d) return -1;
+ break;
+
+ case OP_EXACT:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ if (!inassert) return -1;
+ if (c < 0) c = scode[1];
+ else if (c != scode[1]) return -1;
+ break;
+
+ case OP_EXACTI:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ if (!inassert) return -1;
+ if (c < 0) c = scode[1] | REQ_CASELESS;
+ else if (c != scode[1]) return -1;
+ break;
+ }
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT);
+return c;
+}
+
+
+
+/*************************************************
+* Compile a Regular Expression *
+*************************************************/
+
+/* This function takes a string and returns a pointer to a block of store
+holding a compiled version of the expression. The original API for this
+function had no error code return variable; it is retained for backwards
+compatibility. The new function is given a new name.
+
+Arguments:
+ pattern the regular expression
+ options various option bits
+ errorcodeptr pointer to error code variable (pcre_compile2() only)
+ can be NULL if you don't want a code value
+ errorptr pointer to pointer to error text
+ erroroffset ptr offset in pattern where error was detected
+ tables pointer to character tables or NULL
+
+Returns: pointer to compiled data block, or NULL on error,
+ with errorptr and erroroffset set
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile(const char *pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+#endif
+{
+#ifdef COMPILE_PCRE8
+return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#else
+return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#endif
+}
+
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile2(const char *pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+#endif
+{
+REAL_PCRE *re;
+int length = 1; /* For final END opcode */
+pcre_int32 firstchar, reqchar;
+int newline;
+int errorcode = 0;
+int skipatstart = 0;
+BOOL utf;
+size_t size;
+pcre_uchar *code;
+const pcre_uchar *codestart;
+const pcre_uchar *ptr;
+compile_data compile_block;
+compile_data *cd = &compile_block;
+
+/* This space is used for "compiling" into during the first phase, when we are
+computing the amount of memory that is needed. Compiled items are thrown away
+as soon as possible, so that a fairly large buffer should be sufficient for
+this purpose. The same space is used in the second phase for remembering where
+to fill in forward references to subpatterns. That may overflow, in which case
+new memory is obtained from malloc(). */
+
+pcre_uchar cworkspace[COMPILE_WORK_SIZE];
+
+/* Set this early so that early errors get offset 0. */
+
+ptr = (const pcre_uchar *)pattern;
+
+/* We can't pass back an error message if errorptr is NULL; I guess the best we
+can do is just return NULL, but we can set a code value if there is a code
+pointer. */
+
+if (errorptr == NULL)
+ {
+ if (errorcodeptr != NULL) *errorcodeptr = 99;
+ return NULL;
+ }
+
+*errorptr = NULL;
+if (errorcodeptr != NULL) *errorcodeptr = ERR0;
+
+/* However, we can give a message for this error */
+
+if (erroroffset == NULL)
+ {
+ errorcode = ERR16;
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
+
+*erroroffset = 0;
+
+/* Set up pointers to the individual character tables */
+
+if (tables == NULL) tables = PRIV(default_tables);
+cd->lcc = tables + lcc_offset;
+cd->fcc = tables + fcc_offset;
+cd->cbits = tables + cbits_offset;
+cd->ctypes = tables + ctypes_offset;
+
+/* Check that all undefined public option bits are zero */
+
+if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
+ {
+ errorcode = ERR17;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Check for global one-time settings at the start of the pattern, and remember
+the offset for later. */
+
+while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
+ ptr[skipatstart+1] == CHAR_ASTERISK)
+ {
+ int newnl = 0;
+ int newbsr = 0;
+
+#ifdef COMPILE_PCRE8
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0)
+ { skipatstart += 7; options |= PCRE_UTF8; continue; }
+#endif
+#ifdef COMPILE_PCRE16
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0)
+ { skipatstart += 8; options |= PCRE_UTF16; continue; }
+#endif
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
+ { skipatstart += 6; options |= PCRE_UCP; continue; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
+ { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
+
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
+ { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
+ { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0)
+ { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0)
+ { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0)
+ { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
+
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
+ { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
+ { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
+
+ if (newnl != 0)
+ options = (options & ~PCRE_NEWLINE_BITS) | newnl;
+ else if (newbsr != 0)
+ options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
+ else break;
+ }
+
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (options & PCRE_UTF8) != 0;
+
+/* Can't support UTF unless PCRE has been compiled to include the code. The
+return of an error code from PRIV(valid_utf)() is a new feature, introduced in
+release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is
+not used here. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 &&
+ (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0)
+ {
+#ifdef COMPILE_PCRE8
+ errorcode = ERR44;
+#else
+ errorcode = ERR74;
+#endif
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
+#else
+if (utf)
+ {
+ errorcode = ERR32;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+#endif
+
+/* Can't support UCP unless PCRE has been compiled to include the code. */
+
+#ifndef SUPPORT_UCP
+if ((options & PCRE_UCP) != 0)
+ {
+ errorcode = ERR67;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+#endif
+
+/* Check validity of \R options. */
+
+if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) ==
+ (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+ {
+ errorcode = ERR56;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Handle different types of newline. The three bits give seven cases. The
+current code allows for fixed one- or two-byte sequences, plus "any" and
+"anycrlf". */
+
+switch (options & PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Build-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+if (newline == -2)
+ {
+ cd->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ cd->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ cd->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ cd->nllen = 2;
+ cd->nl[0] = (newline >> 8) & 255;
+ cd->nl[1] = newline & 255;
+ }
+ else
+ {
+ cd->nllen = 1;
+ cd->nl[0] = newline;
+ }
+ }
+
+/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
+references to help in deciding whether (.*) can be treated as anchored or not.
+*/
+
+cd->top_backref = 0;
+cd->backref_map = 0;
+
+/* Reflect pattern for debugging output */
+
+DPRINTF(("------------------------------------------------------------------\n"));
+#ifdef PCRE_DEBUG
+print_puchar(stdout, (PCRE_PUCHAR)pattern);
+#endif
+DPRINTF(("\n"));
+
+/* Pretend to compile the pattern while actually just accumulating the length
+of memory required. This behaviour is triggered by passing a non-NULL final
+argument to compile_regex(). We pass a block of workspace (cworkspace) for it
+to compile parts of the pattern into; the compiled code is discarded when it is
+no longer needed, so hopefully this workspace will never overflow, though there
+is a test for its doing so. */
+
+cd->bracount = cd->final_bracount = 0;
+cd->names_found = 0;
+cd->name_entry_size = 0;
+cd->name_table = NULL;
+cd->start_code = cworkspace;
+cd->hwm = cworkspace;
+cd->start_workspace = cworkspace;
+cd->workspace_size = COMPILE_WORK_SIZE;
+cd->start_pattern = (const pcre_uchar *)pattern;
+cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
+cd->req_varyopt = 0;
+cd->assert_depth = 0;
+cd->external_options = options;
+cd->external_flags = 0;
+cd->open_caps = NULL;
+
+/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
+don't need to look at the result of the function here. The initial options have
+been put into the cd block so that they can be changed if an option setting is
+found within the regex right at the beginning. Bringing initial option settings
+outside can help speed up starting point checks. */
+
+ptr += skipatstart;
+code = cworkspace;
+*code = OP_BRA;
+(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
+ FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length);
+if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
+
+DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
+ (int)(cd->hwm - cworkspace)));
+
+if (length > MAX_PATTERN_SIZE)
+ {
+ errorcode = ERR20;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Compute the size of data block needed and get it, either from malloc or
+externally provided function. Integer overflow should no longer be possible
+because nowadays we limit the maximum value of cd->names_found and
+cd->name_entry_size. */
+
+size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
+re = (REAL_PCRE *)(PUBL(malloc))(size);
+
+if (re == NULL)
+ {
+ errorcode = ERR21;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Put in the magic number, and save the sizes, initial options, internal
+flags, and character table pointer. NULL is used for the default character
+tables. The nullpad field is at the end; it's there to help in the case when a
+regex compiled on a system with 4-byte pointers is run on another with 8-byte
+pointers. */
+
+re->magic_number = MAGIC_NUMBER;
+re->size = (int)size;
+re->options = cd->external_options;
+re->flags = cd->external_flags;
+re->dummy1 = 0;
+re->first_char = 0;
+re->req_char = 0;
+re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
+re->name_entry_size = cd->name_entry_size;
+re->name_count = cd->names_found;
+re->ref_count = 0;
+re->tables = (tables == PRIV(default_tables))? NULL : tables;
+re->nullpad = NULL;
+
+/* The starting points of the name/number translation table and of the code are
+passed around in the compile data block. The start/end pattern and initial
+options are already set from the pre-compile phase, as is the name_entry_size
+field. Reset the bracket count and the names_found field. Also reset the hwm
+field; this time it's used for remembering forward references to subpatterns.
+*/
+
+cd->final_bracount = cd->bracount; /* Save for checking forward references */
+cd->assert_depth = 0;
+cd->bracount = 0;
+cd->names_found = 0;
+cd->name_table = (pcre_uchar *)re + re->name_table_offset;
+codestart = cd->name_table + re->name_entry_size * re->name_count;
+cd->start_code = codestart;
+cd->hwm = (pcre_uchar *)(cd->start_workspace);
+cd->req_varyopt = 0;
+cd->had_accept = FALSE;
+cd->check_lookbehind = FALSE;
+cd->open_caps = NULL;
+
+/* Set up a starting, non-extracting bracket, then compile the expression. On
+error, errorcode will be set non-zero, so we don't need to look at the result
+of the function here. */
+
+ptr = (const pcre_uchar *)pattern + skipatstart;
+code = (pcre_uchar *)codestart;
+*code = OP_BRA;
+(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0,
+ &firstchar, &reqchar, NULL, cd, NULL);
+re->top_bracket = cd->bracount;
+re->top_backref = cd->top_backref;
+re->flags = cd->external_flags | PCRE_MODE;
+
+if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */
+
+/* If not reached end of pattern on success, there's an excess bracket. */
+
+if (errorcode == 0 && *ptr != 0) errorcode = ERR22;
+
+/* Fill in the terminating state and check for disastrous overflow, but
+if debugging, leave the test till after things are printed out. */
+
+*code++ = OP_END;
+
+#ifndef PCRE_DEBUG
+if (code - codestart > length) errorcode = ERR23;
+#endif
+
+/* Fill in any forward references that are required. There may be repeated
+references; optimize for them, as searching a large regex takes time. */
+
+if (cd->hwm > cd->start_workspace)
+ {
+ int prev_recno = -1;
+ const pcre_uchar *groupptr = NULL;
+ while (errorcode == 0 && cd->hwm > cd->start_workspace)
+ {
+ int offset, recno;
+ cd->hwm -= LINK_SIZE;
+ offset = GET(cd->hwm, 0);
+ recno = GET(codestart, offset);
+ if (recno != prev_recno)
+ {
+ groupptr = PRIV(find_bracket)(codestart, utf, recno);
+ prev_recno = recno;
+ }
+ if (groupptr == NULL) errorcode = ERR53;
+ else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart));
+ }
+ }
+
+/* If the workspace had to be expanded, free the new memory. */
+
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+
+/* Give an error if there's back reference to a non-existent capturing
+subpattern. */
+
+if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
+
+/* If there were any lookbehind assertions that contained OP_RECURSE
+(recursions or subroutine calls), a flag is set for them to be checked here,
+because they may contain forward references. Actual recursions can't be fixed
+length, but subroutine calls can. It is done like this so that those without
+OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
+exceptional ones forgo this. We scan the pattern to check that they are fixed
+length, and set their lengths. */
+
+if (cd->check_lookbehind)
+ {
+ pcre_uchar *cc = (pcre_uchar *)codestart;
+
+ /* Loop, searching for OP_REVERSE items, and process those that do not have
+ their length set. (Actually, it will also re-process any that have a length
+ of zero, but that is a pathological case, and it does no harm.) When we find
+ one, we temporarily terminate the branch it is in while we scan it. */
+
+ for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1);
+ cc != NULL;
+ cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1))
+ {
+ if (GET(cc, 1) == 0)
+ {
+ int fixed_length;
+ pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
+ int end_op = *be;
+ *be = OP_END;
+ fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
+ cd);
+ *be = end_op;
+ DPRINTF(("fixed length = %d\n", fixed_length));
+ if (fixed_length < 0)
+ {
+ errorcode = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70 : ERR25;
+ break;
+ }
+ PUT(cc, 1, fixed_length);
+ }
+ cc += 1 + LINK_SIZE;
+ }
+ }
+
+/* Failed to compile, or error while post-processing */
+
+if (errorcode != 0)
+ {
+ (PUBL(free))(re);
+ PCRE_EARLY_ERROR_RETURN:
+ *erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
+ PCRE_EARLY_ERROR_RETURN2:
+ *errorptr = find_error_text(errorcode);
+ if (errorcodeptr != NULL) *errorcodeptr = errorcode;
+ return NULL;
+ }
+
+/* If the anchored option was not passed, set the flag if we can determine that
+the pattern is anchored by virtue of ^ characters or \A or anything else (such
+as starting with .* when DOTALL is set).
+
+Otherwise, if we know what the first byte has to be, save it, because that
+speeds up unanchored matches no end. If not, see if we can set the
+PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
+start with ^. and also when all branches start with .* for non-DOTALL matches.
+*/
+
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ if (is_anchored(codestart, 0, cd->backref_map))
+ re->options |= PCRE_ANCHORED;
+ else
+ {
+ if (firstchar < 0)
+ firstchar = find_firstassertedchar(codestart, FALSE);
+ if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */
+ {
+#ifdef COMPILE_PCRE8
+ re->first_char = firstchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->first_char = firstchar & 0xffff;
+#endif
+#endif
+ if ((firstchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->first_char < 128)
+ {
+ if (cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->first_char) != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->first_char)
+ && cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+
+ re->flags |= PCRE_FIRSTSET;
+ }
+ else if (is_startline(codestart, 0, cd->backref_map))
+ re->flags |= PCRE_STARTLINE;
+ }
+ }
+
+/* For an anchored pattern, we use the "required byte" only if it follows a
+variable length item in the regex. Remove the caseless flag for non-caseable
+bytes. */
+
+if (reqchar >= 0 &&
+ ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0))
+ {
+#ifdef COMPILE_PCRE8
+ re->req_char = reqchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->req_char = reqchar & 0xffff;
+#endif
+#endif
+ if ((reqchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->req_char < 128)
+ {
+ if (cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->req_char) != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+
+ re->flags |= PCRE_REQCHSET;
+ }
+
+/* Print out the compiled data if debugging is enabled. This is never the
+case when building a production library. */
+
+#ifdef PCRE_DEBUG
+printf("Length = %d top_bracket = %d top_backref = %d\n",
+ length, re->top_bracket, re->top_backref);
+
+printf("Options=%08x\n", re->options);
+
+if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ pcre_uchar ch = re->first_char;
+ const char *caseless =
+ ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless);
+ else printf("First char = \\x%02x%s\n", ch, caseless);
+ }
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ pcre_uchar ch = re->req_char;
+ const char *caseless =
+ ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless);
+ else printf("Req char = \\x%02x%s\n", ch, caseless);
+ }
+
+#ifdef COMPILE_PCRE8
+pcre_printint((pcre *)re, stdout, TRUE);
+#else
+pcre16_printint((pcre *)re, stdout, TRUE);
+#endif
+
+/* This check is done here in the debugging case so that the code that
+was compiled can be seen. */
+
+if (code - codestart > length)
+ {
+ (PUBL(free))(re);
+ *errorptr = find_error_text(ERR23);
+ *erroroffset = ptr - (pcre_uchar *)pattern;
+ if (errorcodeptr != NULL) *errorcodeptr = ERR23;
+ return NULL;
+ }
+#endif /* PCRE_DEBUG */
+
+#ifdef COMPILE_PCRE8
+return (pcre *)re;
+#else
+return (pcre16 *)re;
+#endif
+}
+
+/* End of pcre_compile.c */
diff --git a/src/3rdparty/pcre/pcre_config.c b/src/3rdparty/pcre/pcre_config.c
new file mode 100644
index 0000000000..6ebafaf06a
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_config.c
@@ -0,0 +1,170 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_config(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Keep the original link size. */
+static int real_link_size = LINK_SIZE;
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return info about what features are configured *
+*************************************************/
+
+/* This function has an extensible interface so that additional items can be
+added compatibly.
+
+Arguments:
+ what what information is required
+ where where to put the information
+
+Returns: 0 if data returned, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_config(int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_config(int what, void *where)
+#endif
+{
+switch (what)
+ {
+ case PCRE_CONFIG_UTF8:
+#if defined COMPILE_PCRE16
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+#endif
+
+ case PCRE_CONFIG_UTF16:
+#if defined COMPILE_PCRE8
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+#endif
+
+ case PCRE_CONFIG_UNICODE_PROPERTIES:
+#ifdef SUPPORT_UCP
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_JIT:
+#ifdef SUPPORT_JIT
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_JITTARGET:
+#ifdef SUPPORT_JIT
+ *((const char **)where) = PRIV(jit_get_target)();
+#else
+ *((const char **)where) = NULL;
+#endif
+ break;
+
+ case PCRE_CONFIG_NEWLINE:
+ *((int *)where) = NEWLINE;
+ break;
+
+ case PCRE_CONFIG_BSR:
+#ifdef BSR_ANYCRLF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_LINK_SIZE:
+ *((int *)where) = real_link_size;
+ break;
+
+ case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
+ *((int *)where) = POSIX_MALLOC_THRESHOLD;
+ break;
+
+ case PCRE_CONFIG_MATCH_LIMIT:
+ *((unsigned long int *)where) = MATCH_LIMIT;
+ break;
+
+ case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
+ *((unsigned long int *)where) = MATCH_LIMIT_RECURSION;
+ break;
+
+ case PCRE_CONFIG_STACKRECURSE:
+#ifdef NO_RECURSE
+ *((int *)where) = 0;
+#else
+ *((int *)where) = 1;
+#endif
+ break;
+
+ default: return PCRE_ERROR_BADOPTION;
+ }
+
+return 0;
+}
+
+/* End of pcre_config.c */
diff --git a/src/3rdparty/pcre/pcre_dfa_exec.c b/src/3rdparty/pcre/pcre_dfa_exec.c
new file mode 100644
index 0000000000..bc89c0de41
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_dfa_exec.c
@@ -0,0 +1,3490 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language (but see
+below for why this module is different).
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_dfa_exec(), which is an
+alternative matching function that uses a sort of DFA algorithm (not a true
+FSM). This is NOT Perl- compatible, but it has advantages in certain
+applications. */
+
+
+/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
+the performance of his patterns greatly. I could not use it as it stood, as it
+was not thread safe, and made assumptions about pattern sizes. Also, it caused
+test 7 to loop, and test 9 to crash with a segfault.
+
+The issue is the check for duplicate states, which is done by a simple linear
+search up the state list. (Grep for "duplicate" below to find the code.) For
+many patterns, there will never be many states active at one time, so a simple
+linear search is fine. In patterns that have many active states, it might be a
+bottleneck. The suggested code used an indexing scheme to remember which states
+had previously been used for each character, and avoided the linear search when
+it knew there was no chance of a duplicate. This was implemented when adding
+states to the state lists.
+
+I wrote some thread-safe, not-limited code to try something similar at the time
+of checking for duplicates (instead of when adding states), using index vectors
+on the stack. It did give a 13% improvement with one specially constructed
+pattern for certain subject strings, but on other strings and on many of the
+simpler patterns in the test suite it did worse. The major problem, I think,
+was the extra time to initialize the index. This had to be done for each call
+of internal_dfa_exec(). (The supplied patch used a static vector, initialized
+only once - I suspect this was the cause of the problems with the tests.)
+
+Overall, I concluded that the gains in some cases did not outweigh the losses
+in others, so I abandoned this code. */
+
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* For use to indent debugging output */
+
+#define SP " "
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
+into others, under special conditions. A gap of 20 between the blocks should be
+enough. The resulting opcodes don't have to be less than 256 because they are
+never stored, so we push them well clear of the normal opcodes. */
+
+#define OP_PROP_EXTRA 300
+#define OP_EXTUNI_EXTRA 320
+#define OP_ANYNL_EXTRA 340
+#define OP_HSPACE_EXTRA 360
+#define OP_VSPACE_EXTRA 380
+
+
+/* This table identifies those opcodes that are followed immediately by a
+character that is to be tested in some way. This makes it possible to
+centralize the loading of these characters. In the case of Type * etc, the
+"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
+small value. Non-zero values in the table are the offsets from the opcode where
+the character is to be found. ***NOTE*** If the start of this table is
+modified, the three tables that follow must also be modified. */
+
+static const pcre_uint8 coptable[] = {
+ 0, /* End */
+ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
+ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
+ 0, 0, 0, /* Any, AllAny, Anybyte */
+ 0, 0, /* \P, \p */
+ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
+ 0, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
+ 1+IMM2_SIZE, /* exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
+ 1+IMM2_SIZE, /* exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
+ 1+IMM2_SIZE, /* NOT exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
+ 1+IMM2_SIZE, /* NOT exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
+ 1+IMM2_SIZE, /* Type exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
+ 0, 0, /* CRRANGE, CRMINRANGE */
+ 0, /* CLASS */
+ 0, /* NCLASS */
+ 0, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
+ 0, /* DEF */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
+};
+
+/* This table identifies those opcodes that inspect a character. It is used to
+remember the fact that a character could have been inspected when the end of
+the subject is reached. ***NOTE*** If the start of this table is modified, the
+two tables that follow must also be modified. */
+
+static const pcre_uint8 poptable[] = {
+ 0, /* End */
+ 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
+ 1, 1, 1, /* Any, AllAny, Anybyte */
+ 1, 1, /* \P, \p */
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
+ 1, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* upto, minupto, exact */
+ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* NOT upto, minupto, exact */
+ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* NOT upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* Type upto, minupto, exact */
+ 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, /* CRRANGE, CRMINRANGE */
+ 1, /* CLASS */
+ 1, /* NCLASS */
+ 1, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
+ 0, /* DEF */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
+};
+
+/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
+and \w */
+
+static const pcre_uint8 toptable1[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, ctype_digit,
+ ctype_space, ctype_space,
+ ctype_word, ctype_word,
+ 0, 0 /* OP_ANY, OP_ALLANY */
+};
+
+static const pcre_uint8 toptable2[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, 0,
+ ctype_space, 0,
+ ctype_word, 0,
+ 1, 1 /* OP_ANY, OP_ALLANY */
+};
+
+
+/* Structure for holding data about a particular state, which is in effect the
+current data for an active path through the match tree. It must consist
+entirely of ints because the working vector we are passed, and which we put
+these structures in, is a vector of ints. */
+
+typedef struct stateblock {
+ int offset; /* Offset to opcode */
+ int count; /* Count for repeats */
+ int data; /* Some use extra data */
+} stateblock;
+
+#define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int))
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+* Print character string *
+*************************************************/
+
+/* Character string printing function for debugging.
+
+Arguments:
+ p points to string
+ length number of bytes
+ f where to print
+
+Returns: nothing
+*/
+
+static void
+pchars(const pcre_uchar *p, int length, FILE *f)
+{
+int c;
+while (length-- > 0)
+ {
+ if (isprint(c = *(p++)))
+ fprintf(f, "%c", c);
+ else
+ fprintf(f, "\\x%02x", c);
+ }
+}
+#endif
+
+
+
+/*************************************************
+* Execute a Regular Expression - DFA engine *
+*************************************************/
+
+/* This internal function applies a compiled pattern to a subject string,
+starting at a given point, using a DFA engine. This function is called from the
+external one, possibly multiple times if the pattern is not anchored. The
+function calls itself recursively for some kinds of subpattern.
+
+Arguments:
+ md the match_data block with fixed information
+ this_start_code the opening bracket of this subexpression's code
+ current_subject where we currently are in the subject string
+ start_offset start offset in the subject string
+ offsets vector to contain the matching string offsets
+ offsetcount size of same
+ workspace vector of workspace
+ wscount size of same
+ rlevel function call recursion level
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+
+The following macros are used for adding states to the two state vectors (one
+for the current character, one for the following character). */
+
+#define ADD_ACTIVE(x,y) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state++; \
+ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_ACTIVE_DATA(x,y,z) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state->data = (z); \
+ next_active_state++; \
+ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW(x,y) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state++; \
+ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW_DATA(x,y,z) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state->data = (z); \
+ next_new_state++; \
+ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+/* And now, here is the code */
+
+static int
+internal_dfa_exec(
+ dfa_match_data *md,
+ const pcre_uchar *this_start_code,
+ const pcre_uchar *current_subject,
+ int start_offset,
+ int *offsets,
+ int offsetcount,
+ int *workspace,
+ int wscount,
+ int rlevel)
+{
+stateblock *active_states, *new_states, *temp_states;
+stateblock *next_active_state, *next_new_state;
+
+const pcre_uint8 *ctypes, *lcc, *fcc;
+const pcre_uchar *ptr;
+const pcre_uchar *end_code, *first_op;
+
+dfa_recursion_info new_recursive;
+
+int active_count, new_count, match_count;
+
+/* Some fields in the md block are frequently referenced, so we load them into
+independent variables in the hope that this will perform better. */
+
+const pcre_uchar *start_subject = md->start_subject;
+const pcre_uchar *end_subject = md->end_subject;
+const pcre_uchar *start_code = md->start_code;
+
+#ifdef SUPPORT_UTF
+BOOL utf = (md->poptions & PCRE_UTF8) != 0;
+#else
+BOOL utf = FALSE;
+#endif
+
+rlevel++;
+offsetcount &= (-2);
+
+wscount -= 2;
+wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
+ (2 * INTS_PER_STATEBLOCK);
+
+DPRINTF(("\n%.*s---------------------\n"
+ "%.*sCall to internal_dfa_exec f=%d\n",
+ rlevel*2-2, SP, rlevel*2-2, SP, rlevel));
+
+ctypes = md->tables + ctypes_offset;
+lcc = md->tables + lcc_offset;
+fcc = md->tables + fcc_offset;
+
+match_count = PCRE_ERROR_NOMATCH; /* A negative number */
+
+active_states = (stateblock *)(workspace + 2);
+next_new_state = new_states = active_states + wscount;
+new_count = 0;
+
+first_op = this_start_code + 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+
+/* The first thing in any (sub) pattern is a bracket of some sort. Push all
+the alternative states onto the list, and find out where the end is. This
+makes is possible to use this function recursively, when we want to stop at a
+matching internal ket rather than at the end.
+
+If the first opcode in the first alternative is OP_REVERSE, we are dealing with
+a backward assertion. In that case, we have to find out the maximum amount to
+move back, and set up each alternative appropriately. */
+
+if (*first_op == OP_REVERSE)
+ {
+ int max_back = 0;
+ int gone_back;
+
+ end_code = this_start_code;
+ do
+ {
+ int back = GET(end_code, 2+LINK_SIZE);
+ if (back > max_back) max_back = back;
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+
+ /* If we can't go back the amount required for the longest lookbehind
+ pattern, go back as far as we can; some alternatives may still be viable. */
+
+#ifdef SUPPORT_UTF
+ /* In character mode we have to step back character by character */
+
+ if (utf)
+ {
+ for (gone_back = 0; gone_back < max_back; gone_back++)
+ {
+ if (current_subject <= start_subject) break;
+ current_subject--;
+ ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
+ }
+ }
+ else
+#endif
+
+ /* In byte-mode we can do this quickly. */
+
+ {
+ gone_back = (current_subject - max_back < start_subject)?
+ (int)(current_subject - start_subject) : max_back;
+ current_subject -= gone_back;
+ }
+
+ /* Save the earliest consulted character */
+
+ if (current_subject < md->start_used_ptr)
+ md->start_used_ptr = current_subject;
+
+ /* Now we can process the individual branches. */
+
+ end_code = this_start_code;
+ do
+ {
+ int back = GET(end_code, 2+LINK_SIZE);
+ if (back <= gone_back)
+ {
+ int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
+ ADD_NEW_DATA(-bstate, 0, gone_back - back);
+ }
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+ }
+
+/* This is the code for a "normal" subpattern (not a backward assertion). The
+start of a whole pattern is always one of these. If we are at the top level,
+we may be asked to restart matching from the same point that we reached for a
+previous partial match. We still have to scan through the top-level branches to
+find the end state. */
+
+else
+ {
+ end_code = this_start_code;
+
+ /* Restarting */
+
+ if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
+ {
+ do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
+ new_count = workspace[1];
+ if (!workspace[0])
+ memcpy(new_states, active_states, new_count * sizeof(stateblock));
+ }
+
+ /* Not restarting */
+
+ else
+ {
+ int length = 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+ do
+ {
+ ADD_NEW((int)(end_code - start_code + length), 0);
+ end_code += GET(end_code, 1);
+ length = 1 + LINK_SIZE;
+ }
+ while (*end_code == OP_ALT);
+ }
+ }
+
+workspace[0] = 0; /* Bit indicating which vector is current */
+
+DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code)));
+
+/* Loop for scanning the subject */
+
+ptr = current_subject;
+for (;;)
+ {
+ int i, j;
+ int clen, dlen;
+ unsigned int c, d;
+ int forced_fail = 0;
+ BOOL could_continue = FALSE;
+
+ /* Make the new state list into the active state list and empty the
+ new state list. */
+
+ temp_states = active_states;
+ active_states = new_states;
+ new_states = temp_states;
+ active_count = new_count;
+ new_count = 0;
+
+ workspace[0] ^= 1; /* Remember for the restarting feature */
+ workspace[1] = active_count;
+
+#ifdef PCRE_DEBUG
+ printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
+ pchars(ptr, STRLEN_UC(ptr), stdout);
+ printf("\"\n");
+
+ printf("%.*sActive states: ", rlevel*2-2, SP);
+ for (i = 0; i < active_count; i++)
+ printf("%d/%d ", active_states[i].offset, active_states[i].count);
+ printf("\n");
+#endif
+
+ /* Set the pointers for adding new states */
+
+ next_active_state = active_states + active_count;
+ next_new_state = new_states;
+
+ /* Load the current character from the subject outside the loop, as many
+ different states may want to look at it, and we assume that at least one
+ will. */
+
+ if (ptr < end_subject)
+ {
+ clen = 1; /* Number of bytes in the character */
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(c, ptr, clen); } else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+ }
+ else
+ {
+ clen = 0; /* This indicates the end of the subject */
+ c = NOTACHAR; /* This value should never actually be used */
+ }
+
+ /* Scan up the active states and act on each one. The result of an action
+ may be to add more states to the currently active list (e.g. on hitting a
+ parenthesis) or it may be to put states on the new list, for considering
+ when we move the character pointer on. */
+
+ for (i = 0; i < active_count; i++)
+ {
+ stateblock *current_state = active_states + i;
+ BOOL caseless = FALSE;
+ const pcre_uchar *code;
+ int state_offset = current_state->offset;
+ int count, codevalue, rrc;
+
+#ifdef PCRE_DEBUG
+ printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
+ if (clen == 0) printf("EOL\n");
+ else if (c > 32 && c < 127) printf("'%c'\n", c);
+ else printf("0x%02x\n", c);
+#endif
+
+ /* A negative offset is a special case meaning "hold off going to this
+ (negated) state until the number of characters in the data field have
+ been skipped". */
+
+ if (state_offset < 0)
+ {
+ if (current_state->data > 0)
+ {
+ DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
+ ADD_NEW_DATA(state_offset, current_state->count,
+ current_state->data - 1);
+ continue;
+ }
+ else
+ {
+ current_state->offset = state_offset = -state_offset;
+ }
+ }
+
+ /* Check for a duplicate state with the same count, and skip if found.
+ See the note at the head of this module about the possibility of improving
+ performance here. */
+
+ for (j = 0; j < i; j++)
+ {
+ if (active_states[j].offset == state_offset &&
+ active_states[j].count == current_state->count)
+ {
+ DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
+ goto NEXT_ACTIVE_STATE;
+ }
+ }
+
+ /* The state offset is the offset to the opcode */
+
+ code = start_code + state_offset;
+ codevalue = *code;
+
+ /* If this opcode inspects a character, but we are at the end of the
+ subject, remember the fact for use when testing for a partial match. */
+
+ if (clen == 0 && poptable[codevalue] != 0)
+ could_continue = TRUE;
+
+ /* If this opcode is followed by an inline character, load it. It is
+ tempting to test for the presence of a subject character here, but that
+ is wrong, because sometimes zero repetitions of the subject are
+ permitted.
+
+ We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
+ argument that is not a data character - but is always one byte long. We
+ have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in
+ this case. To keep the other cases fast, convert these ones to new opcodes.
+ */
+
+ if (coptable[codevalue] > 0)
+ {
+ dlen = 1;
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
+#endif /* SUPPORT_UTF */
+ d = code[coptable[codevalue]];
+ if (codevalue >= OP_TYPESTAR)
+ {
+ switch(d)
+ {
+ case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
+ case OP_NOTPROP:
+ case OP_PROP: codevalue += OP_PROP_EXTRA; break;
+ case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
+ case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
+ case OP_NOT_HSPACE:
+ case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
+ case OP_NOT_VSPACE:
+ case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
+ default: break;
+ }
+ }
+ }
+ else
+ {
+ dlen = 0; /* Not strictly necessary, but compilers moan */
+ d = NOTACHAR; /* if these variables are not set. */
+ }
+
+
+ /* Now process the individual opcodes */
+
+ switch (codevalue)
+ {
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors coptable or poptable, which are indexed by
+ opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work
+ in the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(coptable) == OP_TABLE_LENGTH) &&
+ (sizeof(poptable) == OP_TABLE_LENGTH)):
+ break;
+
+/* ========================================================================== */
+ /* Reached a closing bracket. If not at the end of the pattern, carry
+ on with the next opcode. For repeating opcodes, also add the repeat
+ state. Note that KETRPOS will always be encountered at the end of the
+ subpattern, because the possessive subpattern repeats are always handled
+ using recursive calls. Thus, it never adds any new states.
+
+ At the end of the (sub)pattern, unless we have an empty string and
+ PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
+ start of the subject, save the match data, shifting up all previous
+ matches so we always have the longest first. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ if (code != end_code)
+ {
+ ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
+ if (codevalue != OP_KET)
+ {
+ ADD_ACTIVE(state_offset - GET(code, 1), 0);
+ }
+ }
+ else
+ {
+ if (ptr > current_subject ||
+ ((md->moptions & PCRE_NOTEMPTY) == 0 &&
+ ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 ||
+ current_subject > start_subject + md->start_offset)))
+ {
+ if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
+ else if (match_count > 0 && ++match_count * 2 > offsetcount)
+ match_count = 0;
+ count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
+ if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
+ if (offsetcount >= 2)
+ {
+ offsets[0] = (int)(current_subject - start_subject);
+ offsets[1] = (int)(ptr - start_subject);
+ DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
+ offsets[1] - offsets[0], current_subject));
+ }
+ if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
+ {
+ DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+ "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
+ match_count, rlevel*2-2, SP));
+ return match_count;
+ }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes add to the current list of states without looking
+ at the current character. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALT:
+ do { code += GET(code, 1); } while (*code == OP_ALT);
+ ADD_ACTIVE((int)(code - start_code), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRA:
+ case OP_SBRA:
+ do
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CBRA:
+ case OP_SCBRA:
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
+ code += GET(code, 1);
+ while (*code == OP_ALT)
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ ADD_ACTIVE(state_offset + 1, 0);
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SKIPZERO:
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRC:
+ if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRCM:
+ if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
+ (ptr != end_subject && WAS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EOD:
+ if (ptr >= end_subject)
+ {
+ if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOD:
+ if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOM:
+ if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+
+/* ========================================================================== */
+ /* These opcodes inspect the next subject character, and sometimes
+ the previous one as well, but do not have an argument. The variable
+ clen contains the length of the current character and is zero if we are
+ at the end of the subject. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANY:
+ if (clen > 0 && !IS_NEWLINE(ptr))
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALLANY:
+ if (clen > 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EODN:
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLL:
+ if ((md->moptions & PCRE_NOTEOL) == 0)
+ {
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
+ (ptr == end_subject - md->nllen)
+ ))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLLM:
+ if ((md->moptions & PCRE_NOTEOL) == 0)
+ {
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ else if (IS_NEWLINE(ptr))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+
+ case OP_DIGIT:
+ case OP_WHITESPACE:
+ case OP_WORDCHAR:
+ if (clen > 0 && c < 256 &&
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ if (clen > 0 && (c >= 256 ||
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ {
+ int left_word, right_word;
+
+ if (ptr > start_subject)
+ {
+ const pcre_uchar *temp = ptr - 1;
+ if (temp < md->start_used_ptr) md->start_used_ptr = temp;
+#ifdef SUPPORT_UTF
+ if (utf) { BACKCHAR(temp); }
+#endif
+ GETCHARTEST(d, temp);
+#ifdef SUPPORT_UCP
+ if ((md->poptions & PCRE_UCP) != 0)
+ {
+ if (d == '_') left_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(d);
+ left_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
+ }
+ else left_word = FALSE;
+
+ if (clen > 0)
+ {
+#ifdef SUPPORT_UCP
+ if ((md->poptions & PCRE_UCP) != 0)
+ {
+ if (c == '_') right_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ right_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
+ }
+ else right_word = FALSE;
+
+ if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+
+ /*-----------------------------------------------------------------*/
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs.
+ */
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
+ }
+ break;
+#endif
+
+
+
+/* ========================================================================== */
+ /* These opcodes likewise inspect the subject character, but have an
+ argument that is not a data character. It is one of these opcodes:
+ OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
+ OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (count > 0 && codevalue == OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + 2, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are virtual opcodes that are used when something like
+ OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
+ argument. It keeps the code above fast for the other cases. The argument
+ is in the d variable. */
+
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEPLUS:
+ case OP_PROP_EXTRA + OP_TYPEMINPLUS:
+ case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL01;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL01:
+ case 0x000a:
+ if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEQUERY:
+ case OP_PROP_EXTRA + OP_TYPEMINQUERY:
+ case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
+ count = 4;
+ goto QS1;
+
+ case OP_PROP_EXTRA + OP_TYPESTAR:
+ case OP_PROP_EXTRA + OP_TYPEMINSTAR:
+ case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS1:
+
+ ADD_ACTIVE(state_offset + 4, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS2;
+
+ case OP_EXTUNI_EXTRA + OP_TYPESTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS2:
+
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS3;
+
+ case OP_ANYNL_EXTRA + OP_TYPESTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS3:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL02;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL02:
+ case 0x000a:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS4;
+
+ case OP_VSPACE_EXTRA + OP_TYPESTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS4:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS5;
+
+ case OP_HSPACE_EXTRA + OP_TYPESTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS5:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEEXACT:
+ case OP_PROP_EXTRA + OP_TYPEUPTO:
+ case OP_PROP_EXTRA + OP_TYPEMINUPTO:
+ case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1 + IMM2_SIZE + 1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[1 + IMM2_SIZE + 2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
+ case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEEXACT:
+ case OP_ANYNL_EXTRA + OP_TYPEUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL03;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL03:
+ case 0x000a:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_VSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_HSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes are followed by a character that is usually compared
+ to the current subject character; it is loaded into d. We still get
+ here even if there is no subject character, because in some cases zero
+ repetitions are permitted. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHAR:
+ if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHARI:
+ if (clen == 0) break;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
+ {
+ unsigned int othercase;
+ if (c < 128)
+ othercase = fcc[c];
+ else
+ /* If we have Unicode property support, we can use it to test the
+ other case of the character. */
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE(c);
+#else
+ othercase = NOTACHAR;
+#endif
+
+ if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
+ { ADD_NEW(state_offset + 2, 0); }
+ }
+ break;
+
+
+#ifdef SUPPORT_UCP
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky one because it can match more than one character.
+ Find out how many characters to skip, and then set up a negative state
+ to wait for them to pass before continuing. */
+
+ case OP_EXTUNI:
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ while (nptr < end_subject)
+ {
+ int nclen = 1;
+ GETCHARLEN(c, nptr, nclen);
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ ncount++;
+ nptr += nclen;
+ }
+ ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky like EXTUNI because it too can match more than one
+ character (when CR is followed by LF). In this case, set up a negative
+ state to wait for one character to pass before continuing. */
+
+ case OP_ANYNL:
+ if (clen > 0) switch(c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+
+ case 0x000a:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a)
+ {
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else
+ {
+ ADD_NEW(state_offset + 1, 0);
+ }
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ default: break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character casefully. This is only used for
+ one-byte characters, that is, we know that d < 256. The character we are
+ checking (c) can be multibyte. */
+
+ case OP_NOT:
+ if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character caselessly. This is only used for
+ one-byte characters, that is, we know that d < 256. The character we are
+ checking (c) can be multibyte. */
+
+ case OP_NOTI:
+ if (clen > 0 && c != d && c != fcc[d])
+ { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+
+ /* Fall through */
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (count > 0 &&
+ (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + dlen + 1, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPOSSTAR:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXACTI:
+ case OP_NOTEXACTI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_EXACT:
+ case OP_NOTEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTPOSUPTO:
+ ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* These are the class-handling opcodes */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+ {
+ BOOL isinclass = FALSE;
+ int next_state_offset;
+ const pcre_uchar *ecode;
+
+ /* For a simple class, there is always just a 32-byte table, and we
+ can set isinclass from it. */
+
+ if (codevalue != OP_XCLASS)
+ {
+ ecode = code + 1 + (32 / sizeof(pcre_uchar));
+ if (clen > 0)
+ {
+ isinclass = (c > 255)? (codevalue == OP_NCLASS) :
+ ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0);
+ }
+ }
+
+ /* An extended class may have a table or a list of single characters,
+ ranges, or both, and it may be positive or negative. There's a
+ function that sorts all this out. */
+
+ else
+ {
+ ecode = code + GET(code, 1);
+ if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
+ }
+
+ /* At this point, isinclass is set for all kinds of class, and ecode
+ points to the byte after the end of the class. If there is a
+ quantifier, this is where it will be. */
+
+ next_state_offset = (int)(ecode - start_code);
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass) { ADD_NEW(state_offset, 0); }
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
+ if (isinclass) { count++; ADD_NEW(state_offset, count); }
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ count = current_state->count; /* Already matched */
+ if (count >= GET2(ecode, 1))
+ { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ if (isinclass)
+ {
+ int max = GET2(ecode, 1 + IMM2_SIZE);
+ if (++count >= max && max != 0) /* Max 0 => no limit */
+ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ break;
+
+ default:
+ if (isinclass) { ADD_NEW(next_state_offset, 0); }
+ break;
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are the opcodes for fancy brackets of various kinds. We have
+ to use recursion in order to handle them. The "always failing" assertion
+ (?!) is optimised to OP_FAIL when compiling, so we have to support that,
+ though the other "backtracking verbs" are not supported. */
+
+ case OP_FAIL:
+ forced_fail++; /* Count FAILs for multiple states */
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ {
+ int rc;
+ int local_offsets[2];
+ int local_workspace[1000];
+ const pcre_uchar *endasscode = code + GET(code, 1);
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_exec(
+ md, /* static match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+ if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_COND:
+ case OP_SCOND:
+ {
+ int local_offsets[1000];
+ int local_workspace[1000];
+ int codelink = GET(code, 1);
+ int condcode;
+
+ /* Because of the way auto-callout works during compile, a callout item
+ is inserted between OP_COND and an assertion condition. This does not
+ happen for the other conditions. */
+
+ if (code[LINK_SIZE+1] == OP_CALLOUT)
+ {
+ rrc = 0;
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 1; /* Version 1 of the callout block */
+ cb.callout_number = code[LINK_SIZE+2];
+ cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
+ cb.subject_length = (int)(end_subject - start_subject);
+ cb.start_match = (int)(current_subject - start_subject);
+ cb.current_position = (int)(ptr - start_subject);
+ cb.pattern_position = GET(code, LINK_SIZE + 3);
+ cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
+ cb.capture_top = 1;
+ cb.capture_last = -1;
+ cb.callout_data = md->callout_data;
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
+ }
+ if (rrc > 0) break; /* Fail this thread */
+ code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */
+ }
+
+ condcode = code[LINK_SIZE+1];
+
+ /* Back reference conditions are not supported */
+
+ if (condcode == OP_CREF || condcode == OP_NCREF)
+ return PCRE_ERROR_DFA_UCOND;
+
+ /* The DEFINE condition is always false */
+
+ if (condcode == OP_DEF)
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+
+ /* The only supported version of OP_RREF is for the value RREF_ANY,
+ which means "test if in any recursion". We can't test for specifically
+ recursed groups. */
+
+ else if (condcode == OP_RREF || condcode == OP_NRREF)
+ {
+ int value = GET2(code, LINK_SIZE + 2);
+ if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
+ if (md->recursive != NULL)
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
+ else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+
+ /* Otherwise, the condition is an assertion */
+
+ else
+ {
+ int rc;
+ const pcre_uchar *asscode = code + LINK_SIZE + 1;
+ const pcre_uchar *endasscode = asscode + GET(asscode, 1);
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ asscode, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+ if ((rc >= 0) ==
+ (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ else
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_RECURSE:
+ {
+ dfa_recursion_info *ri;
+ int local_offsets[1000];
+ int local_workspace[1000];
+ const pcre_uchar *callpat = start_code + GET(code, 1);
+ int recno = (callpat == md->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
+ int rc;
+
+ DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP));
+
+ /* Check for repeating a recursion without advancing the subject
+ pointer. This should catch convoluted mutual recursions. (Some simple
+ cases are caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && ptr == ri->subject_position)
+ return PCRE_ERROR_RECURSELOOP;
+
+ /* Remember this recursion and where we started it so as to
+ catch infinite loops. */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = ptr;
+ new_recursive.prevrec = md->recursive;
+ md->recursive = &new_recursive;
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ callpat, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ md->recursive = new_recursive.prevrec; /* Done this recursion */
+
+ DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP,
+ rc));
+
+ /* Ran out of internal offsets */
+
+ if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
+
+ /* For each successful matched substring, set up the next state with a
+ count of characters to skip before trying it. Note that the count is in
+ characters, not bytes. */
+
+ if (rc > 0)
+ {
+ for (rc = rc*2 - 2; rc >= 0; rc -= 2)
+ {
+ int charcount = local_offsets[rc+1] - local_offsets[rc];
+#ifdef SUPPORT_UTF
+ const pcre_uchar *p = start_subject + local_offsets[rc];
+ const pcre_uchar *pp = start_subject + local_offsets[rc+1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ if (charcount > 0)
+ {
+ ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
+ }
+ else
+ {
+ ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
+ }
+ }
+ }
+ else if (rc != PCRE_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ {
+ int charcount, matched_count;
+ const pcre_uchar *local_ptr = ptr;
+ BOOL allow_zero;
+
+ if (codevalue == OP_BRAPOSZERO)
+ {
+ allow_zero = TRUE;
+ codevalue = *(++code); /* Codevalue will be one of above BRAs */
+ }
+ else allow_zero = FALSE;
+
+ /* Loop to match the subpattern as many times as possible as if it were
+ a complete pattern. */
+
+ for (matched_count = 0;; matched_count++)
+ {
+ int local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_exec(
+ md, /* fixed match data */
+ code, /* this subexpression's code */
+ local_ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ /* Failed to match */
+
+ if (rc < 0)
+ {
+ if (rc != PCRE_ERROR_NOMATCH) return rc;
+ break;
+ }
+
+ /* Matched: break the loop if zero characters matched. */
+
+ charcount = local_offsets[1] - local_offsets[0];
+ if (charcount == 0) break;
+ local_ptr += charcount; /* Advance temporary position ptr */
+ }
+
+ /* At this point we have matched the subpattern matched_count
+ times, and local_ptr is pointing to the character after the end of the
+ last match. */
+
+ if (matched_count > 0 || allow_zero)
+ {
+ const pcre_uchar *end_subpattern = code;
+ int next_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr = local_ptr;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+ }
+ else
+ {
+ const pcre_uchar *p = ptr;
+ const pcre_uchar *pp = local_ptr;
+ charcount = (int)(pp - p);
+#ifdef SUPPORT_UTF
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+ }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ {
+ int local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_exec(
+ md, /* fixed match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc >= 0)
+ {
+ const pcre_uchar *end_subpattern = code;
+ int charcount = local_offsets[1] - local_offsets[0];
+ int next_state_offset, repeat_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* If the end of this subpattern is KETRMAX or KETRMIN, we must
+ arrange for the repeat state also to be added to the relevant list.
+ Calculate the offset, or set -1 for no repeat. */
+
+ repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
+ *end_subpattern == OP_KETRMIN)?
+ (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
+
+ /* If we have matched an empty string, add the next state at the
+ current character pointer. This is important so that the duplicate
+ checking kicks in, which is what breaks infinite loops that match an
+ empty string. */
+
+ if (charcount == 0)
+ {
+ ADD_ACTIVE(next_state_offset, 0);
+ }
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ else if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr += charcount;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+
+ /* If we are adding a repeat state at the new character position,
+ we must fudge things so that it is the only current state.
+ Otherwise, it might be a duplicate of one we processed before, and
+ that would cause it to be skipped. */
+
+ if (repeat_state_offset >= 0)
+ {
+ next_active_state = active_states;
+ active_count = 0;
+ i = -1;
+ ADD_ACTIVE(repeat_state_offset, 0);
+ }
+ }
+ else
+ {
+#ifdef SUPPORT_UTF
+ const pcre_uchar *p = start_subject + local_offsets[0];
+ const pcre_uchar *pp = start_subject + local_offsets[1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+ if (repeat_state_offset >= 0)
+ { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
+ }
+ }
+ else if (rc != PCRE_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* Handle callouts */
+
+ case OP_CALLOUT:
+ rrc = 0;
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 1; /* Version 1 of the callout block */
+ cb.callout_number = code[1];
+ cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
+ cb.subject_length = (int)(end_subject - start_subject);
+ cb.start_match = (int)(current_subject - start_subject);
+ cb.current_position = (int)(ptr - start_subject);
+ cb.pattern_position = GET(code, 2);
+ cb.next_item_length = GET(code, 2 + LINK_SIZE);
+ cb.capture_top = 1;
+ cb.capture_last = -1;
+ cb.callout_data = md->callout_data;
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
+ }
+ if (rrc == 0)
+ { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); }
+ break;
+
+
+/* ========================================================================== */
+ default: /* Unsupported opcode */
+ return PCRE_ERROR_DFA_UITEM;
+ }
+
+ NEXT_ACTIVE_STATE: continue;
+
+ } /* End of loop scanning active states */
+
+ /* We have finished the processing at the current subject character. If no
+ new states have been set for the next character, we have found all the
+ matches that we are going to find. If we are at the top level and partial
+ matching has been requested, check for appropriate conditions.
+
+ The "forced_ fail" variable counts the number of (*F) encountered for the
+ character. If it is equal to the original active_count (saved in
+ workspace[1]) it means that (*F) was found on every active state. In this
+ case we don't want to give a partial match.
+
+ The "could_continue" variable is true if a state could have continued but
+ for the fact that the end of the subject was reached. */
+
+ if (new_count <= 0)
+ {
+ if (rlevel == 1 && /* Top level, and */
+ could_continue && /* Some could go on */
+ forced_fail != workspace[1] && /* Not all forced fail & */
+ ( /* either... */
+ (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */
+ || /* or... */
+ ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */
+ match_count < 0) /* no matches */
+ ) && /* And... */
+ ptr >= end_subject && /* Reached end of subject */
+ ptr > md->start_used_ptr) /* Inspected non-empty string */
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = (int)(md->start_used_ptr - start_subject);
+ offsets[1] = (int)(end_subject - start_subject);
+ }
+ match_count = PCRE_ERROR_PARTIAL;
+ }
+
+ DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+ "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
+ rlevel*2-2, SP));
+ break; /* In effect, "return", but see the comment below */
+ }
+
+ /* One or more states are active for the next character. */
+
+ ptr += clen; /* Advance to next subject character */
+ } /* Loop to move along the subject string */
+
+/* Control gets here from "break" a few lines above. We do it this way because
+if we use "return" above, we have compiler trouble. Some compilers warn if
+there's nothing here because they think the function doesn't return a value. On
+the other hand, if we put a dummy statement here, some more clever compilers
+complain that it can't be reached. Sigh. */
+
+return match_count;
+}
+
+
+
+
+/*************************************************
+* Execute a Regular Expression - DFA engine *
+*************************************************/
+
+/* This external function applies a compiled re to a subject string using a DFA
+engine. This function calls the internal function multiple times if the pattern
+is not anchored.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ offsets vector of match offsets
+ offsetcount size of same
+ workspace workspace vector
+ wscount size of same
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
+ const char *subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount, int *workspace, int wscount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount, int *workspace, int wscount)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+dfa_match_data match_block;
+dfa_match_data *md = &match_block;
+BOOL utf, anchored, startline, firstline;
+const pcre_uchar *current_subject, *end_subject;
+const pcre_study_data *study = NULL;
+
+const pcre_uchar *req_char_ptr;
+const pcre_uint8 *start_bits = NULL;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
+int newline;
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || workspace == NULL ||
+ (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
+if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
+
+/* We need to find the pointer to any study data before we test for byte
+flipping, so we scan the extra_data block first. This may set two fields in the
+match block, so we must initialize them beforehand. However, the other fields
+in the match block must not be set until after the byte flipping. */
+
+md->tables = re->tables;
+md->callout_data = NULL;
+
+if (extra_data != NULL)
+ {
+ unsigned int flags = extra_data->flags;
+ if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+ return PCRE_ERROR_DFA_UMLIMIT;
+ if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+ md->callout_data = extra_data->callout_data;
+ if ((flags & PCRE_EXTRA_TABLES) != 0)
+ md->tables = extra_data->tables;
+ }
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* Set some local values */
+
+current_subject = (const pcre_uchar *)subject + start_offset;
+end_subject = (const pcre_uchar *)subject + length;
+req_char_ptr = current_subject - 1;
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (re->options & PCRE_UTF8) != 0;
+#else
+utf = FALSE;
+#endif
+
+anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
+ (re->options & PCRE_ANCHORED) != 0;
+
+/* The remaining fixed data for passing around. */
+
+md->start_code = (const pcre_uchar *)argument_re +
+ re->name_table_offset + re->name_count * re->name_entry_size;
+md->start_subject = (const pcre_uchar *)subject;
+md->end_subject = end_subject;
+md->start_offset = start_offset;
+md->moptions = options;
+md->poptions = re->options;
+
+/* If the BSR option is not set at match time, copy what was set
+at compile time. */
+
+if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
+ {
+ if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+ md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
+#ifdef BSR_ANYCRLF
+ else md->moptions |= PCRE_BSR_ANYCRLF;
+#endif
+ }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
+ PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Compile-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+if (newline == -2)
+ {
+ md->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ md->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ md->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ md->nllen = 2;
+ md->nl[0] = (newline >> 8) & 255;
+ md->nl[1] = newline & 255;
+ }
+ else
+ {
+ md->nllen = 1;
+ md->nl[0] = newline;
+ }
+ }
+
+/* Check a UTF-8 string if required. Unfortunately there's no way of passing
+back the character offset. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
+ {
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset);
+ if (errorcode != 0)
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+ return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
+ }
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
+ }
+#endif
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (md->tables == NULL) md->tables = PRIV(default_tables);
+
+/* The "must be at the start of a line" flags are used in a loop when finding
+where to start. */
+
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* Set up the first character to match, if available. The first_byte value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
+ }
+ else
+ {
+ if (!startline && study != NULL &&
+ (study->flags & PCRE_STUDY_MAPPED) != 0)
+ start_bits = study->start_bits;
+ }
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
+ }
+
+/* Call the main matching function, looping for a non-anchored regex after a
+failed match. If not restarting, perform certain optimizations at the start of
+a match. */
+
+for (;;)
+ {
+ int rc;
+
+ if ((options & PCRE_DFA_RESTART) == 0)
+ {
+ const pcre_uchar *save_end_subject = end_subject;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. Implement this by temporarily adjusting
+ end_subject so that we stop scanning at a newline. If the match fails at
+ the newline, later code breaks this loop. */
+
+ if (firstline)
+ {
+ PCRE_PUCHAR t = current_subject;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (t < md->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found. However, there is an option that disables
+ these, for testing and for ensuring that all callouts do actually occur.
+ The option can be set in the regex by (*NO_START_OPT) or passed in
+ match-time options. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ /* Advance to a known first char. */
+
+ if (has_first_char)
+ {
+ if (first_char != first_char2)
+ while (current_subject < end_subject &&
+ *current_subject != first_char && *current_subject != first_char2)
+ current_subject++;
+ else
+ while (current_subject < end_subject &&
+ *current_subject != first_char)
+ current_subject++;
+ }
+
+ /* Or to just after a linebreak for a multiline match if possible */
+
+ else if (startline)
+ {
+ if (current_subject > md->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (current_subject < end_subject &&
+ !WAS_NEWLINE(current_subject))
+ {
+ current_subject++;
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+ }
+ }
+ else
+#endif
+ while (current_subject < end_subject && !WAS_NEWLINE(current_subject))
+ current_subject++;
+
+ /* If we have just passed a CR and the newline option is ANY or
+ ANYCRLF, and we are now at a LF, advance the match position by one
+ more character. */
+
+ if (current_subject[-1] == CHAR_CR &&
+ (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+ current_subject < end_subject &&
+ *current_subject == CHAR_NL)
+ current_subject++;
+ }
+ }
+
+ /* Or to a non-unique first char after study */
+
+ else if (start_bits != NULL)
+ {
+ while (current_subject < end_subject)
+ {
+ register unsigned int c = *current_subject;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) == 0)
+ {
+ current_subject++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+#endif
+ }
+ else break;
+ }
+ }
+ }
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching or if
+ disabling is explicitly requested (and of course, by the test above, this
+ code is not obeyed when restarting after a partial match). */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 &&
+ (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
+ {
+ /* If the pattern was studied, a minimum subject length may be set. This
+ is a lower bound; no actual string of that length may actually match the
+ pattern. Although the value is, strictly, in characters, we treat it as
+ bytes to avoid spending too much time in this optimization. */
+
+ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+ (pcre_uint32)(end_subject - current_subject) < study->minlength)
+ return PCRE_ERROR_NOMATCH;
+
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
+ must be later in the subject; otherwise the test starts at the match
+ point. This optimization can save a huge amount of work in patterns with
+ nested unlimited repeats that aren't going to match. Writing separate
+ code for cased/caseless versions makes it go faster, as does using an
+ autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary
+ patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
+ string... so we don't do this when the string is sufficiently long. */
+
+ if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX)
+ {
+ register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_char_ptr)
+ {
+ if (req_char != req_char2)
+ {
+ while (p < end_subject)
+ {
+ register int pp = *p++;
+ if (pp == req_char || pp == req_char2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (*p++ == req_char) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required character, break the matching loop,
+ which will cause a return or PCRE_ERROR_NOMATCH. */
+
+ if (p >= end_subject) break;
+
+ /* If we have found the required character, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this character yet. */
+
+ req_char_ptr = p;
+ }
+ }
+ }
+ } /* End of optimizations that are done when not restarting */
+
+ /* OK, now we can do the business */
+
+ md->start_used_ptr = current_subject;
+ md->recursive = NULL;
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ md->start_code, /* this subexpression's code */
+ current_subject, /* where we currently are */
+ start_offset, /* start offset in subject */
+ offsets, /* offset vector */
+ offsetcount, /* size of same */
+ workspace, /* workspace vector */
+ wscount, /* size of same */
+ 0); /* function recurse level */
+
+ /* Anything other than "no match" means we are done, always; otherwise, carry
+ on only if not anchored. */
+
+ if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;
+
+ /* Advance to the next subject character unless we are at the end of a line
+ and firstline is set. */
+
+ if (firstline && IS_NEWLINE(current_subject)) break;
+ current_subject++;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+ }
+#endif
+ if (current_subject > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more character. */
+
+ if (current_subject[-1] == CHAR_CR &&
+ current_subject < end_subject &&
+ *current_subject == CHAR_NL &&
+ (re->flags & PCRE_HASCRORLF) == 0 &&
+ (md->nltype == NLTYPE_ANY ||
+ md->nltype == NLTYPE_ANYCRLF ||
+ md->nllen == 2))
+ current_subject++;
+
+ } /* "Bumpalong" loop */
+
+return PCRE_ERROR_NOMATCH;
+}
+
+/* End of pcre_dfa_exec.c */
diff --git a/src/3rdparty/pcre/pcre_exec.c b/src/3rdparty/pcre/pcre_exec.c
new file mode 100644
index 0000000000..2905808c83
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_exec.c
@@ -0,0 +1,6960 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains pcre_exec(), the externally visible function that does
+pattern matching using an NFA algorithm, trying to mimic Perl as closely as
+possible. There are also some static supporting functions. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+/* Undefine some potentially clashing cpp symbols */
+
+#undef min
+#undef max
+
+/* Values for setting in md->match_function_type to indicate two special types
+of call to match(). We do it this way to save on using another stack variable,
+as stack usage is to be discouraged. */
+
+#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
+#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
+
+/* Non-error returns from the match() function. Error returns are externally
+defined PCRE_ERROR_xxx codes, which are all negative. */
+
+#define MATCH_MATCH 1
+#define MATCH_NOMATCH 0
+
+/* Special internal returns from the match() function. Make them sufficiently
+negative to avoid the external error codes. */
+
+#define MATCH_ACCEPT (-999)
+#define MATCH_COMMIT (-998)
+#define MATCH_KETRPOS (-997)
+#define MATCH_ONCE (-996)
+#define MATCH_PRUNE (-995)
+#define MATCH_SKIP (-994)
+#define MATCH_SKIP_ARG (-993)
+#define MATCH_THEN (-992)
+
+/* Maximum number of ints of offset to save on the stack for recursive calls.
+If the offset vector is bigger, malloc is used. This should be a multiple of 3,
+because the offset vector is always a multiple of 3 long. */
+
+#define REC_STACK_SAVE_MAX 30
+
+/* Min and max values for the common repeats; for the maxima, 0 => infinity */
+
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
+
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+* Debugging function to print chars *
+*************************************************/
+
+/* Print a sequence of chars in printable format, stopping at the end of the
+subject if the requested.
+
+Arguments:
+ p points to characters
+ length number to print
+ is_subject TRUE if printing from within md->start_subject
+ md pointer to matching data block, if is_subject is TRUE
+
+Returns: nothing
+*/
+
+static void
+pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
+{
+unsigned int c;
+if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
+while (length-- > 0)
+ if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
+}
+#endif
+
+
+
+/*************************************************
+* Match a back-reference *
+*************************************************/
+
+/* Normally, if a back reference hasn't been set, the length that is passed is
+negative, so the match always fails. However, in JavaScript compatibility mode,
+the length passed is zero. Note that in caseless UTF-8 mode, the number of
+subject bytes matched may be different to the number of reference bytes.
+
+Arguments:
+ offset index into the offset vector
+ eptr pointer into the subject
+ length length of reference to be matched (number of bytes)
+ md points to match data block
+ caseless TRUE if caseless
+
+Returns: < 0 if not matched, otherwise the number of subject bytes matched
+*/
+
+static int
+match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
+ BOOL caseless)
+{
+PCRE_PUCHAR eptr_start = eptr;
+register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
+
+#ifdef PCRE_DEBUG
+if (eptr >= md->end_subject)
+ printf("matching subject <null>");
+else
+ {
+ printf("matching subject ");
+ pchars(eptr, length, TRUE, md);
+ }
+printf(" against backref ");
+pchars(p, length, FALSE, md);
+printf("\n");
+#endif
+
+/* Always fail if reference not set (and not JavaScript compatible). */
+
+if (length < 0) return -1;
+
+/* Separate the caseless case for speed. In UTF-8 mode we can only do this
+properly if Unicode properties are supported. Otherwise, we can check only
+ASCII characters. */
+
+if (caseless)
+ {
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (md->utf)
+ {
+ /* Match characters up to the end of the reference. NOTE: the number of
+ bytes matched may differ, because there are some characters whose upper and
+ lower case versions code as different numbers of bytes. For example, U+023A
+ (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
+ a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
+ the latter. It is important, therefore, to check the length along the
+ reference, not along the subject (earlier code did this wrong). */
+
+ PCRE_PUCHAR endptr = p + length;
+ while (p < endptr)
+ {
+ int c, d;
+ if (eptr >= md->end_subject) return -1;
+ GETCHARINC(c, eptr);
+ GETCHARINC(d, p);
+ if (c != d && c != UCD_OTHERCASE(d)) return -1;
+ }
+ }
+ else
+#endif
+#endif
+
+ /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
+ is no UCP support. */
+ {
+ if (eptr + length > md->end_subject) return -1;
+ while (length-- > 0)
+ {
+ if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
+ p++;
+ eptr++;
+ }
+ }
+ }
+
+/* In the caseful case, we can just compare the bytes, whether or not we
+are in UTF-8 mode. */
+
+else
+ {
+ if (eptr + length > md->end_subject) return -1;
+ while (length-- > 0) if (*p++ != *eptr++) return -1;
+ }
+
+return (int)(eptr - eptr_start);
+}
+
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+The match() function is highly recursive, though not every recursive call
+increases the recursive depth. Nevertheless, some regular expressions can cause
+it to recurse to a great depth. I was writing for Unix, so I just let it call
+itself recursively. This uses the stack for saving everything that has to be
+saved for a recursive call. On Unix, the stack can be large, and this works
+fine.
+
+It turns out that on some non-Unix-like systems there are problems with
+programs that use a lot of stack. (This despite the fact that every last chip
+has oodles of memory these days, and techniques for extending the stack have
+been known for decades.) So....
+
+There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
+calls by keeping local variables that need to be preserved in blocks of memory
+obtained from malloc() instead instead of on the stack. Macros are used to
+achieve this so that the actual code doesn't look very different to what it
+always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
+****************************************************************************
+***************************************************************************/
+
+/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
+below must be updated in sync. */
+
+enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
+ RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+ RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+ RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
+ RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
+ RM61, RM62, RM63, RM64, RM65, RM66 };
+
+/* These versions of the macros use the stack, as normal. There are debugging
+versions and production versions. Note that the "rw" argument of RMATCH isn't
+actually used in this definition. */
+
+#ifndef NO_RECURSE
+#define REGISTER register
+
+#ifdef PCRE_DEBUG
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ { \
+ printf("match() called in line %d\n", __LINE__); \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
+ printf("to line %d\n", __LINE__); \
+ }
+#define RRETURN(ra) \
+ { \
+ printf("match() returned %d from line %d ", ra, __LINE__); \
+ return ra; \
+ }
+#else
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
+#define RRETURN(ra) return ra
+#endif
+
+#else
+
+
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the md
+argument of match(), which never changes. */
+
+#define REGISTER
+
+#define RMATCH(ra,rb,rc,rd,re,rw)\
+ {\
+ heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
+ if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
+ frame->Xwhere = rw; \
+ newframe->Xeptr = ra;\
+ newframe->Xecode = rb;\
+ newframe->Xmstart = mstart;\
+ newframe->Xoffset_top = rc;\
+ newframe->Xeptrb = re;\
+ newframe->Xrdepth = frame->Xrdepth + 1;\
+ newframe->Xprevframe = frame;\
+ frame = newframe;\
+ DPRINTF(("restarting from line %d\n", __LINE__));\
+ goto HEAP_RECURSE;\
+ L_##rw:\
+ DPRINTF(("jumped back to line %d\n", __LINE__));\
+ }
+
+#define RRETURN(ra)\
+ {\
+ heapframe *oldframe = frame;\
+ frame = oldframe->Xprevframe;\
+ if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\
+ if (frame != NULL)\
+ {\
+ rrc = ra;\
+ goto HEAP_RETURN;\
+ }\
+ return ra;\
+ }
+
+
+/* Structure for remembering the local variables in a private frame */
+
+typedef struct heapframe {
+ struct heapframe *Xprevframe;
+
+ /* Function arguments that may change */
+
+ PCRE_PUCHAR Xeptr;
+ const pcre_uchar *Xecode;
+ PCRE_PUCHAR Xmstart;
+ int Xoffset_top;
+ eptrblock *Xeptrb;
+ unsigned int Xrdepth;
+
+ /* Function local variables */
+
+ PCRE_PUCHAR Xcallpat;
+#ifdef SUPPORT_UTF
+ PCRE_PUCHAR Xcharptr;
+#endif
+ PCRE_PUCHAR Xdata;
+ PCRE_PUCHAR Xnext;
+ PCRE_PUCHAR Xpp;
+ PCRE_PUCHAR Xprev;
+ PCRE_PUCHAR Xsaved_eptr;
+
+ recursion_info Xnew_recursive;
+
+ BOOL Xcur_is_word;
+ BOOL Xcondition;
+ BOOL Xprev_is_word;
+
+#ifdef SUPPORT_UCP
+ int Xprop_type;
+ int Xprop_value;
+ int Xprop_fail_result;
+ int Xoclength;
+ pcre_uchar Xocchars[6];
+#endif
+
+ int Xcodelink;
+ int Xctype;
+ unsigned int Xfc;
+ int Xfi;
+ int Xlength;
+ int Xmax;
+ int Xmin;
+ int Xnumber;
+ int Xoffset;
+ int Xop;
+ int Xsave_capture_last;
+ int Xsave_offset1, Xsave_offset2, Xsave_offset3;
+ int Xstacksave[REC_STACK_SAVE_MAX];
+
+ eptrblock Xnewptrb;
+
+ /* Where to jump back to */
+
+ int Xwhere;
+
+} heapframe;
+
+#endif
+
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+* Match from current position *
+*************************************************/
+
+/* This function is called recursively in many circumstances. Whenever it
+returns a negative (error) response, the outer incarnation must also return the
+same response. */
+
+/* These macros pack up tests that are used for partial matching, and which
+appear several times in the code. We set the "hit end" flag if the pointer is
+at the end of the subject and also past the start of the subject (i.e.
+something has been matched). For hard partial matching, we then return
+immediately. The second one is used when we already know we are past the end of
+the subject. */
+
+#define CHECK_PARTIAL()\
+ if (md->partial != 0 && eptr >= md->end_subject && \
+ eptr > md->start_used_ptr) \
+ { \
+ md->hitend = TRUE; \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
+ }
+
+#define SCHECK_PARTIAL()\
+ if (md->partial != 0 && eptr > md->start_used_ptr) \
+ { \
+ md->hitend = TRUE; \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
+ }
+
+
+/* Performance note: It might be tempting to extract commonly used fields from
+the md structure (e.g. utf, end_subject) into individual variables to improve
+performance. Tests using gcc on a SPARC disproved this; in the first case, it
+made performance worse.
+
+Arguments:
+ eptr pointer to current character in subject
+ ecode pointer to current position in compiled code
+ mstart pointer to the current match start position (can be modified
+ by encountering \K)
+ offset_top current top pointer
+ md pointer to "static" info for the match
+ eptrb pointer to chain of blocks containing eptr at start of
+ brackets - for testing for empty matches
+ rdepth the recursion depth
+
+Returns: MATCH_MATCH if matched ) these values are >= 0
+ MATCH_NOMATCH if failed to match )
+ a negative MATCH_xxx value for PRUNE, SKIP, etc
+ a negative PCRE_ERROR_xxx value if aborted by an error condition
+ (e.g. stopped by repeated call or recursion limit)
+*/
+
+static int
+match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
+ PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
+ unsigned int rdepth)
+{
+/* These variables do not need to be preserved over recursion in this function,
+so they can be ordinary variables in all cases. Mark some of them with
+"register" because they are used a lot in loops. */
+
+register int rrc; /* Returns from recursive calls */
+register int i; /* Used for loops not involving calls to RMATCH() */
+register unsigned int c; /* Character values not kept over RMATCH() calls */
+register BOOL utf; /* Local copy of UTF flag for speed */
+
+BOOL minimize, possessive; /* Quantifier options */
+BOOL caseless;
+int condcode;
+
+/* When recursion is not being used, all "local" variables that have to be
+preserved over calls to RMATCH() are part of a "frame". We set up the top-level
+frame on the stack here; subsequent instantiations are obtained from the heap
+whenever RMATCH() does a "recursion". See the macro definitions above. Putting
+the top-level on the stack rather than malloc-ing them all gives a performance
+boost in many cases where there is not much "recursion". */
+
+#ifdef NO_RECURSE
+heapframe frame_zero;
+heapframe *frame = &frame_zero;
+frame->Xprevframe = NULL; /* Marks the top level */
+
+/* Copy in the original argument variables */
+
+frame->Xeptr = eptr;
+frame->Xecode = ecode;
+frame->Xmstart = mstart;
+frame->Xoffset_top = offset_top;
+frame->Xeptrb = eptrb;
+frame->Xrdepth = rdepth;
+
+/* This is where control jumps back to to effect "recursion" */
+
+HEAP_RECURSE:
+
+/* Macros make the argument variables come from the current frame */
+
+#define eptr frame->Xeptr
+#define ecode frame->Xecode
+#define mstart frame->Xmstart
+#define offset_top frame->Xoffset_top
+#define eptrb frame->Xeptrb
+#define rdepth frame->Xrdepth
+
+/* Ditto for the local variables */
+
+#ifdef SUPPORT_UTF
+#define charptr frame->Xcharptr
+#endif
+#define callpat frame->Xcallpat
+#define codelink frame->Xcodelink
+#define data frame->Xdata
+#define next frame->Xnext
+#define pp frame->Xpp
+#define prev frame->Xprev
+#define saved_eptr frame->Xsaved_eptr
+
+#define new_recursive frame->Xnew_recursive
+
+#define cur_is_word frame->Xcur_is_word
+#define condition frame->Xcondition
+#define prev_is_word frame->Xprev_is_word
+
+#ifdef SUPPORT_UCP
+#define prop_type frame->Xprop_type
+#define prop_value frame->Xprop_value
+#define prop_fail_result frame->Xprop_fail_result
+#define oclength frame->Xoclength
+#define occhars frame->Xocchars
+#endif
+
+#define ctype frame->Xctype
+#define fc frame->Xfc
+#define fi frame->Xfi
+#define length frame->Xlength
+#define max frame->Xmax
+#define min frame->Xmin
+#define number frame->Xnumber
+#define offset frame->Xoffset
+#define op frame->Xop
+#define save_capture_last frame->Xsave_capture_last
+#define save_offset1 frame->Xsave_offset1
+#define save_offset2 frame->Xsave_offset2
+#define save_offset3 frame->Xsave_offset3
+#define stacksave frame->Xstacksave
+
+#define newptrb frame->Xnewptrb
+
+/* When recursion is being used, local variables are allocated on the stack and
+get preserved during recursion in the normal way. In this environment, fi and
+i, and fc and c, can be the same variables. */
+
+#else /* NO_RECURSE not defined */
+#define fi i
+#define fc c
+
+/* Many of the following variables are used only in small blocks of the code.
+My normal style of coding would have declared them within each of those blocks.
+However, in order to accommodate the version of this code that uses an external
+"stack" implemented on the heap, it is easier to declare them all here, so the
+declarations can be cut out in a block. The only declarations within blocks
+below are for variables that do not have to be preserved over a recursive call
+to RMATCH(). */
+
+#ifdef SUPPORT_UTF
+const pcre_uchar *charptr;
+#endif
+const pcre_uchar *callpat;
+const pcre_uchar *data;
+const pcre_uchar *next;
+PCRE_PUCHAR pp;
+const pcre_uchar *prev;
+PCRE_PUCHAR saved_eptr;
+
+recursion_info new_recursive;
+
+BOOL cur_is_word;
+BOOL condition;
+BOOL prev_is_word;
+
+#ifdef SUPPORT_UCP
+int prop_type;
+int prop_value;
+int prop_fail_result;
+int oclength;
+pcre_uchar occhars[6];
+#endif
+
+int codelink;
+int ctype;
+int length;
+int max;
+int min;
+int number;
+int offset;
+int op;
+int save_capture_last;
+int save_offset1, save_offset2, save_offset3;
+int stacksave[REC_STACK_SAVE_MAX];
+
+eptrblock newptrb;
+
+/* There is a special fudge for calling match() in a way that causes it to
+measure the size of its basic stack frame when the stack is being used for
+recursion. The second argument (ecode) being NULL triggers this behaviour. It
+cannot normally ever be NULL. The return is the negated value of the frame
+size. */
+
+if (ecode == NULL)
+ {
+ if (rdepth == 0)
+ return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
+ else
+ {
+ int len = (char *)&rdepth - (char *)eptr;
+ return (len > 0)? -len : len;
+ }
+ }
+#endif /* NO_RECURSE */
+
+/* To save space on the stack and in the heap frame, I have doubled up on some
+of the local variables that are used only in localised parts of the code, but
+still need to be preserved over recursive calls of match(). These macros define
+the alternative names that are used. */
+
+#define allow_zero cur_is_word
+#define cbegroup condition
+#define code_offset codelink
+#define condassert condition
+#define matched_once prev_is_word
+#define foc number
+#define save_mark data
+
+/* These statements are here to stop the compiler complaining about unitialized
+variables. */
+
+#ifdef SUPPORT_UCP
+prop_value = 0;
+prop_fail_result = 0;
+#endif
+
+
+/* This label is used for tail recursion, which is used in a few cases even
+when NO_RECURSE is not defined, in order to reduce the amount of stack that is
+used. Thanks to Ian Taylor for noticing this possibility and sending the
+original patch. */
+
+TAIL_RECURSE:
+
+/* OK, now we can get on with the real code of the function. Recursive calls
+are specified by the macro RMATCH and RRETURN is used to return. When
+NO_RECURSE is *not* defined, these just turn into a recursive call to match()
+and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
+defined). However, RMATCH isn't like a function call because it's quite a
+complicated macro. It has to be used in one particular way. This shouldn't,
+however, impact performance when true recursion is being used. */
+
+#ifdef SUPPORT_UTF
+utf = md->utf; /* Local copy of the flag */
+#else
+utf = FALSE;
+#endif
+
+/* First check that we haven't called match() too many times, or that we
+haven't exceeded the recursive call limit. */
+
+if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
+if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
+
+/* At the start of a group with an unlimited repeat that may match an empty
+string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is
+done this way to save having to use another function argument, which would take
+up space on the stack. See also MATCH_CONDASSERT below.
+
+When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
+such remembered pointers, to be checked when we hit the closing ket, in order
+to break infinite loops that match no characters. When match() is called in
+other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
+NOT be used with tail recursion, because the memory block that is used is on
+the stack, so a new one may be required for each match(). */
+
+if (md->match_function_type == MATCH_CBEGROUP)
+ {
+ newptrb.epb_saved_eptr = eptr;
+ newptrb.epb_prev = eptrb;
+ eptrb = &newptrb;
+ md->match_function_type = 0;
+ }
+
+/* Now start processing the opcodes. */
+
+for (;;)
+ {
+ minimize = possessive = FALSE;
+ op = *ecode;
+
+ switch(op)
+ {
+ case OP_MARK:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM55);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+
+ /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
+ argument, and we must check whether that argument matches this MARK's
+ argument. It is passed back in md->start_match_ptr (an overloading of that
+ variable). If it does match, we reset that variable to the current subject
+ position and return MATCH_SKIP. Otherwise, pass back the return code
+ unaltered. */
+
+ else if (rrc == MATCH_SKIP_ARG &&
+ STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
+ {
+ md->start_match_ptr = eptr;
+ RRETURN(MATCH_SKIP);
+ }
+ RRETURN(rrc);
+
+ case OP_FAIL:
+ RRETURN(MATCH_NOMATCH);
+
+ /* COMMIT overrides PRUNE, SKIP, and THEN */
+
+ case OP_COMMIT:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM52);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
+ rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
+ rrc != MATCH_THEN)
+ RRETURN(rrc);
+ RRETURN(MATCH_COMMIT);
+
+ /* PRUNE overrides THEN */
+
+ case OP_PRUNE:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM51);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ case OP_PRUNE_ARG:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM56);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ /* SKIP overrides PRUNE and THEN */
+
+ case OP_SKIP:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM53);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
+ RRETURN(rrc);
+ md->start_match_ptr = eptr; /* Pass back current position */
+ RRETURN(MATCH_SKIP);
+
+ /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+ nomatch_mark. There is a flag that disables this opcode when re-matching a
+ pattern that ended with a SKIP for which there was not a matching MARK. */
+
+ case OP_SKIP_ARG:
+ if (md->ignore_skip_arg)
+ {
+ ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
+ break;
+ }
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM57);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
+ RRETURN(rrc);
+
+ /* Pass back the current skip name by overloading md->start_match_ptr and
+ returning the special MATCH_SKIP_ARG return code. This will either be
+ caught by a matching MARK, or get to the top, where it causes a rematch
+ with the md->ignore_skip_arg flag set. */
+
+ md->start_match_ptr = ecode + 2;
+ RRETURN(MATCH_SKIP_ARG);
+
+ /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
+ the branch in which it occurs can be determined. Overload the start of
+ match pointer to do this. */
+
+ case OP_THEN:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM54);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ case OP_THEN_ARG:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
+ md, eptrb, RM58);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ /* Handle an atomic group that does not contain any capturing parentheses.
+ This can be handled like an assertion. Prior to 8.13, all atomic groups
+ were handled this way. In 8.13, the code was changed as below for ONCE, so
+ that backups pass through the group and thereby reset captured values.
+ However, this uses a lot more stack, so in 8.20, atomic groups that do not
+ contain any captures generate OP_ONCE_NC, which can be handled in the old,
+ less stack intensive way.
+
+ Check the alternative branches in turn - the matching won't pass the KET
+ for this kind of subpattern. If any one branch matches, we carry on as at
+ the end of a normal bracket, leaving the subject pointer, but resetting
+ the start-of-match value in case it was changed by \K. */
+
+ case OP_ONCE_NC:
+ prev = ecode;
+ saved_eptr = eptr;
+ save_mark = md->mark;
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
+ if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
+ {
+ mstart = md->start_match_ptr;
+ break;
+ }
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ md->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ /* If hit the end of the group (which could be repeated), fail */
+
+ if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+
+ /* Continue as from after the group, updating the offsets high water
+ mark, since extracts may have been taken. */
+
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+
+ /* For a non-repeating ket, just continue at this level. This also
+ happens for a repeating ket if no characters were matched in the group.
+ This is the forcible breaking of infinite loops as implemented in Perl
+ 5.005. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ ecode += 1+LINK_SIZE;
+ break;
+ }
+
+ /* The repeating kets try the rest of the pattern or restart from the
+ preceding bracket, in the appropriate order. The second "call" of match()
+ uses tail recursion, to avoid using another stack frame. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Handle a capturing bracket, other than those that are possessive with an
+ unlimited repeat. If there is space in the offset vector, save the current
+ subject position in the working slot at the top of the vector. We mustn't
+ change the current values of the data slot, because they may be set from a
+ previous iteration of this group, and be referred to by a reference inside
+ the group. A failure to match might occur after the group has succeeded,
+ if something later on doesn't match. For this reason, we need to restore
+ the working value and also the values of the final offsets, in case they
+ were set by a previous iteration of the same bracket.
+
+ If there isn't enough space in the offset vector, treat this as if it were
+ a non-capturing bracket. Don't worry about setting the flag for the error
+ case here; that is handled in the code for KET. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("start bracket %d\n", number);
+ printf("subject=");
+ pchars(eptr, 16, TRUE, md);
+ printf("\n");
+#endif
+
+ if (offset < md->offset_max)
+ {
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
+ save_mark = md->mark;
+
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM1);
+ if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
+
+ /* If we backed up to a THEN, check whether it is within the current
+ branch by comparing the address of the THEN that is passed back with
+ the end of the branch. If it is within the current branch, and the
+ branch is one of two or more alternatives (it either starts or ends
+ with OP_ALT), we have reached the limit of THEN's action, so convert
+ the return code to NOMATCH, which will cause normal backtracking to
+ happen from now on. Otherwise, THEN is passed back to an outer
+ alternative. This implements Perl's treatment of parenthesized groups,
+ where a group not containing | does not affect the current alternative,
+ that is, (X) is NOT the same as (X|(*F)). */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ /* Anything other than NOMATCH is passed back. */
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
+
+ DPRINTF(("bracket %d failed\n", number));
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
+
+ /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
+
+ RRETURN(rrc);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing or atomic group, except for possessive with unlimited
+ repeat and ONCE group with no captures. Loop for all the alternatives.
+
+ When we get to the final alternative within the brackets, we used to return
+ the result of a recursive call to match() whatever happened so it was
+ possible to reduce stack usage by turning this into a tail recursion,
+ except in the case of a possibly empty group. However, now that there is
+ the possiblity of (*THEN) occurring in the final alternative, this
+ optimization is no longer always possible.
+
+ We can optimize if we know there are no (*THEN)s in the pattern; at present
+ this is the best that can be done.
+
+ MATCH_ONCE is returned when the end of an atomic group is successfully
+ reached, but subsequent matching fails. It passes back up the tree (causing
+ captured values to be reset) until the original atomic group level is
+ reached. This is tested by comparing md->once_target with the start of the
+ group. At this point, the return is converted into MATCH_NOMATCH so that
+ previous backup points can be taken. */
+
+ case OP_ONCE:
+ case OP_BRA:
+ case OP_SBRA:
+ DPRINTF(("start non-capturing bracket\n"));
+
+ for (;;)
+ {
+ if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;
+
+ /* If this is not a possibly empty group, and there are no (*THEN)s in
+ the pattern, and this is the final alternative, optimize as described
+ above. */
+
+ else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
+ {
+ ecode += PRIV(OP_lengths)[*ecode];
+ goto TAIL_RECURSE;
+ }
+
+ /* In all other cases, we have to make another call to match(). */
+
+ save_mark = md->mark;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
+ RM2);
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH)
+ {
+ if (rrc == MATCH_ONCE)
+ {
+ const pcre_uchar *scode = ecode;
+ if (*scode != OP_ONCE) /* If not at start, find it */
+ {
+ while (*scode == OP_ALT) scode += GET(scode, 1);
+ scode -= GET(scode, 1);
+ }
+ if (md->once_target == scode) rrc = MATCH_NOMATCH;
+ }
+ RRETURN(rrc);
+ }
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
+
+ RRETURN(MATCH_NOMATCH);
+
+ /* Handle possessive capturing brackets with an unlimited repeat. We come
+ here from BRAZERO with allow_zero set TRUE. The offset_vector values are
+ handled similarly to the normal case above. However, the matching is
+ different. The end of these brackets will always be OP_KETRPOS, which
+ returns MATCH_KETRPOS without going further in the pattern. By this means
+ we can handle the group by iteration rather than recursion, thereby
+ reducing the amount of stack needed. */
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_CAPTURE:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("start possessive bracket %d\n", number);
+ printf("subject=");
+ pchars(eptr, 16, TRUE, md);
+ printf("\n");
+#endif
+
+ if (offset < md->offset_max)
+ {
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
+
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+
+ /* Each time round the loop, save the current subject position for use
+ when the group matches. For MATCH_MATCH, the group has matched, so we
+ restart it with a new subject starting position, remembering that we had
+ at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
+ usual. If we haven't matched any alternatives in any iteration, check to
+ see if a previous iteration matched. If so, the group has matched;
+ continue from afterwards. Otherwise it has failed; restore the previous
+ capture values before returning NOMATCH. */
+
+ for (;;)
+ {
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM63);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ save_capture_last = md->capture_last;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (!matched_once)
+ {
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
+ }
+
+ if (allow_zero || matched_once)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing possessive bracket with unlimited repeat. We come here
+ from BRAZERO with allow_zero = TRUE. The code is similar to the above,
+ without the capturing complication. It is written out separately for speed
+ and cleanliness. */
+
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_NON_CAPTURE:
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM48);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (matched_once || allow_zero)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+ RRETURN(MATCH_NOMATCH);
+
+ /* Control never reaches here. */
+
+ /* Conditional group: compilation checked that there are no more than
+ two branches. If the condition is false, skipping the first branch takes us
+ past the end if there is only one branch, but that's OK because that is
+ exactly what going to the ket would do. */
+
+ case OP_COND:
+ case OP_SCOND:
+ codelink = GET(ecode, 1);
+
+ /* Because of the way auto-callout works during compile, a callout item is
+ inserted between OP_COND and an assertion condition. */
+
+ if (ecode[LINK_SIZE+1] == OP_CALLOUT)
+ {
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
+ cb.callout_number = ecode[LINK_SIZE+2];
+ cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
+ cb.subject_length = (int)(md->end_subject - md->start_subject);
+ cb.start_match = (int)(mstart - md->start_subject);
+ cb.current_position = (int)(eptr - md->start_subject);
+ cb.pattern_position = GET(ecode, LINK_SIZE + 3);
+ cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
+ cb.capture_top = offset_top/2;
+ cb.capture_last = md->capture_last;
+ cb.callout_data = md->callout_data;
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+ ecode += PRIV(OP_lengths)[OP_CALLOUT];
+ }
+
+ condcode = ecode[LINK_SIZE+1];
+
+ /* Now see what the actual condition is */
+
+ if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
+ {
+ if (md->recursive == NULL) /* Not recursing => FALSE */
+ {
+ condition = FALSE;
+ ecode += GET(ecode, 1);
+ }
+ else
+ {
+ int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
+ condition = (recno == RREF_ANY || recno == md->recursive->group_num);
+
+ /* If the test is for recursion into a specific subpattern, and it is
+ false, but the test was set up by name, scan the table to see if the
+ name refers to any other numbers, and test them. The condition is true
+ if any one is set. */
+
+ if (!condition && condcode == OP_NRREF)
+ {
+ pcre_uchar *slotA = md->name_table;
+ for (i = 0; i < md->name_count; i++)
+ {
+ if (GET2(slotA, 0) == recno) break;
+ slotA += md->name_entry_size;
+ }
+
+ /* Found a name for the number - there can be only one; duplicate
+ names for different numbers are allowed, but not vice versa. First
+ scan down for duplicates. */
+
+ if (i < md->name_count)
+ {
+ pcre_uchar *slotB = slotA;
+ while (slotB > md->name_table)
+ {
+ slotB -= md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == md->recursive->group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < md->name_count; i++)
+ {
+ slotB += md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == md->recursive->group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+ }
+
+ /* Chose branch according to the condition */
+
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
+ }
+ }
+
+ else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
+ {
+ offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
+ condition = offset < offset_top && md->offset_vector[offset] >= 0;
+
+ /* If the numbered capture is unset, but the reference was by name,
+ scan the table to see if the name refers to any other numbers, and test
+ them. The condition is true if any one is set. This is tediously similar
+ to the code above, but not close enough to try to amalgamate. */
+
+ if (!condition && condcode == OP_NCREF)
+ {
+ int refno = offset >> 1;
+ pcre_uchar *slotA = md->name_table;
+
+ for (i = 0; i < md->name_count; i++)
+ {
+ if (GET2(slotA, 0) == refno) break;
+ slotA += md->name_entry_size;
+ }
+
+ /* Found a name for the number - there can be only one; duplicate names
+ for different numbers are allowed, but not vice versa. First scan down
+ for duplicates. */
+
+ if (i < md->name_count)
+ {
+ pcre_uchar *slotB = slotA;
+ while (slotB > md->name_table)
+ {
+ slotB -= md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ offset = GET2(slotB, 0) << 1;
+ condition = offset < offset_top &&
+ md->offset_vector[offset] >= 0;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < md->name_count; i++)
+ {
+ slotB += md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ offset = GET2(slotB, 0) << 1;
+ condition = offset < offset_top &&
+ md->offset_vector[offset] >= 0;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+ }
+
+ /* Chose branch according to the condition */
+
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
+ }
+
+ else if (condcode == OP_DEF) /* DEFINE - always false */
+ {
+ condition = FALSE;
+ ecode += GET(ecode, 1);
+ }
+
+ /* The condition is an assertion. Call match() to evaluate it - setting
+ md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
+ an assertion. */
+
+ else
+ {
+ md->match_function_type = MATCH_CONDASSERT;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
+ if (rrc == MATCH_MATCH)
+ {
+ if (md->end_offset_top > offset_top)
+ offset_top = md->end_offset_top; /* Captures may have happened */
+ condition = TRUE;
+ ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
+ while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ }
+
+ /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
+ assertion; it is therefore treated as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+ {
+ RRETURN(rrc); /* Need braces because of following else */
+ }
+ else
+ {
+ condition = FALSE;
+ ecode += codelink;
+ }
+ }
+
+ /* We are now at the branch that is to be obeyed. As there is only one, can
+ use tail recursion to avoid using another stack frame, except when there is
+ unlimited repeat of a possibly empty group. In the latter case, a recursive
+ call to match() is always required, unless the second alternative doesn't
+ exist, in which case we can just plough on. Note that, for compatibility
+ with Perl, the | in a conditional group is NOT treated as creating two
+ alternatives. If a THEN is encountered in the branch, it propagates out to
+ the enclosing alternative (unless nested in a deeper set of alternatives,
+ of course). */
+
+ if (condition || *ecode == OP_ALT)
+ {
+ if (op != OP_SCOND)
+ {
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
+ RRETURN(rrc);
+ }
+
+ /* Condition false & no alternative; continue after the group. */
+
+ else
+ {
+ ecode += 1 + LINK_SIZE;
+ }
+ break;
+
+
+ /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
+ to close any currently open capturing brackets. */
+
+ case OP_CLOSE:
+ number = GET2(ecode, 1);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("end bracket %d at *ACCEPT", number);
+ printf("\n");
+#endif
+
+ md->capture_last = number;
+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ {
+ md->offset_vector[offset] =
+ md->offset_vector[md->offset_end - number];
+ md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
+ if (offset_top <= offset) offset_top = offset + 2;
+ }
+ ecode += 1 + IMM2_SIZE;
+ break;
+
+
+ /* End of the pattern, either real or forced. */
+
+ case OP_END:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+
+ /* If we have matched an empty string, fail if not in an assertion and not
+ in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART
+ is set and we have matched at the start of the subject. In both cases,
+ backtracking will then try other alternatives, if any. */
+
+ if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
+ md->recursive == NULL &&
+ (md->notempty ||
+ (md->notempty_atstart &&
+ mstart == md->start_subject + md->start_offset)))
+ RRETURN(MATCH_NOMATCH);
+
+ /* Otherwise, we have a match. */
+
+ md->end_match_ptr = eptr; /* Record where we ended */
+ md->end_offset_top = offset_top; /* and how many extracts were taken */
+ md->start_match_ptr = mstart; /* and the start (\K can modify) */
+
+ /* For some reason, the macros don't work properly if an expression is
+ given as the argument to RRETURN when the heap is in use. */
+
+ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
+ RRETURN(rrc);
+
+ /* Assertion brackets. Check the alternative branches in turn - the
+ matching won't pass the KET for an assertion. If any one branch matches,
+ the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
+ start of each branch to move the current point backwards, so the code at
+ this level is identical to the lookahead case. When the assertion is part
+ of a condition, we want to return immediately afterwards. The caller of
+ this incarnation of the match() function will have set MATCH_CONDASSERT in
+ md->match_function type, and one of these opcodes will be the first opcode
+ that is processed. We use a local variable that is preserved over calls to
+ match() to remember this case. */
+
+ case OP_ASSERT:
+ case OP_ASSERTBACK:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ mstart = md->start_match_ptr; /* In case \K reset it */
+ break;
+ }
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it is treated
+ as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
+
+ /* If checking an assertion for a condition, return MATCH_MATCH. */
+
+ if (condassert) RRETURN(MATCH_MATCH);
+
+ /* Continue from after the assertion, updating the offsets high water
+ mark, since extracts may have been taken during the assertion. */
+
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ ecode += 1 + LINK_SIZE;
+ offset_top = md->end_offset_top;
+ continue;
+
+ /* Negative assertion: all branches must fail to match. Encountering SKIP,
+ PRUNE, or COMMIT means we must assume failure without checking subsequent
+ branches. */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK_NOT:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
+ md->mark = save_mark;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
+ if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
+ {
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ break;
+ }
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it is treated
+ as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ }
+ while (*ecode == OP_ALT);
+
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+
+ ecode += 1 + LINK_SIZE;
+ continue;
+
+ /* Move the subject pointer back. This occurs only at the start of
+ each branch of a lookbehind assertion. If we are too close to the start to
+ move back, this match function fails. When working with UTF-8 we move
+ back a number of characters, not bytes. */
+
+ case OP_REVERSE:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ i = GET(ecode, 1);
+ while (i-- > 0)
+ {
+ eptr--;
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+
+ /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+
+ {
+ eptr -= GET(ecode, 1);
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Save the earliest consulted character, then skip to next op code */
+
+ if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
+ ecode += 1 + LINK_SIZE;
+ break;
+
+ /* The callout item calls an external function, if one is provided, passing
+ details of the match so far. This is mainly for debugging, though the
+ function is able to force a failure. */
+
+ case OP_CALLOUT:
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
+ cb.callout_number = ecode[1];
+ cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
+ cb.subject_length = (int)(md->end_subject - md->start_subject);
+ cb.start_match = (int)(mstart - md->start_subject);
+ cb.current_position = (int)(eptr - md->start_subject);
+ cb.pattern_position = GET(ecode, 2);
+ cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
+ cb.capture_top = offset_top/2;
+ cb.capture_last = md->capture_last;
+ cb.callout_data = md->callout_data;
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+ ecode += 2 + 2*LINK_SIZE;
+ break;
+
+ /* Recursion either matches the current regex, or some subexpression. The
+ offset data is the offset to the starting bracket from the start of the
+ whole pattern. (This is so that it works from duplicated subpatterns.)
+
+ The state of the capturing groups is preserved over recursion, and
+ re-instated afterwards. We don't know how many are started and not yet
+ finished (offset_top records the completed total) so we just have to save
+ all the potential data. There may be up to 65535 such values, which is too
+ large to put on the stack, but using malloc for small numbers seems
+ expensive. As a compromise, the stack is used when there are no more than
+ REC_STACK_SAVE_MAX values to store; otherwise malloc is used.
+
+ There are also other values that have to be saved. We use a chained
+ sequence of blocks that actually live on the stack. Thanks to Robin Houston
+ for the original version of this logic. It has, however, been hacked around
+ a lot, so he is not to blame for the current way it works. */
+
+ case OP_RECURSE:
+ {
+ recursion_info *ri;
+ int recno;
+
+ callpat = md->start_code + GET(ecode, 1);
+ recno = (callpat == md->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
+
+ /* Check for repeating a recursion without advancing the subject pointer.
+ This should catch convoluted mutual recursions. (Some simple cases are
+ caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && eptr == ri->subject_position)
+ RRETURN(PCRE_ERROR_RECURSELOOP);
+
+ /* Add to "recursing stack" */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = eptr;
+ new_recursive.prevrec = md->recursive;
+ md->recursive = &new_recursive;
+
+ /* Where to continue from afterwards */
+
+ ecode += 1 + LINK_SIZE;
+
+ /* Now save the offset data */
+
+ new_recursive.saved_max = md->offset_end;
+ if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
+ new_recursive.offset_save = stacksave;
+ else
+ {
+ new_recursive.offset_save =
+ (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
+ if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
+ }
+ memcpy(new_recursive.offset_save, md->offset_vector,
+ new_recursive.saved_max * sizeof(int));
+
+ /* OK, now we can do the recursion. After processing each alternative,
+ restore the offset data. If there were nested recursions, md->recursive
+ might be changed, so reset it before looping. */
+
+ DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
+ cbegroup = (*callpat >= OP_SBRA);
+ do
+ {
+ if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
+ md, eptrb, RM6);
+ memcpy(md->offset_vector, new_recursive.offset_save,
+ new_recursive.saved_max * sizeof(int));
+ md->recursive = new_recursive.prevrec;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ DPRINTF(("Recursion matched\n"));
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+
+ /* Set where we got to in the subject, and reset the start in case
+ it was changed by \K. This *is* propagated back out of a recursion,
+ for Perl compatibility. */
+
+ eptr = md->end_match_ptr;
+ mstart = md->start_match_ptr;
+ goto RECURSION_MATCHED; /* Exit loop; end processing */
+ }
+
+ /* PCRE does not allow THEN to escape beyond a recursion; it is treated
+ as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+ {
+ DPRINTF(("Recursion gave error %d\n", rrc));
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+ RRETURN(rrc);
+ }
+
+ md->recursive = &new_recursive;
+ callpat += GET(callpat, 1);
+ }
+ while (*callpat == OP_ALT);
+
+ DPRINTF(("Recursion didn't match\n"));
+ md->recursive = new_recursive.prevrec;
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ RECURSION_MATCHED:
+ break;
+
+ /* An alternation is the end of a branch; scan along to find the end of the
+ bracketed group and go to there. */
+
+ case OP_ALT:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ break;
+
+ /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
+ indicating that it may occur zero times. It may repeat infinitely, or not
+ at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
+ with fixed upper repeat limits are compiled as a number of copies, with the
+ optional ones preceded by BRAZERO or BRAMINZERO. */
+
+ case OP_BRAZERO:
+ next = ecode + 1;
+ RMATCH(eptr, next, offset_top, md, eptrb, RM10);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ do next += GET(next, 1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
+ break;
+
+ case OP_BRAMINZERO:
+ next = ecode + 1;
+ do next += GET(next, 1); while (*next == OP_ALT);
+ RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode++;
+ break;
+
+ case OP_SKIPZERO:
+ next = ecode+1;
+ do next += GET(next,1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
+ break;
+
+ /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
+ here; just jump to the group, with allow_zero set TRUE. */
+
+ case OP_BRAPOSZERO:
+ op = *(++ecode);
+ allow_zero = TRUE;
+ if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
+ goto POSSESSIVE_NON_CAPTURE;
+
+ /* End of a group, repeated or non-repeating. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ prev = ecode - GET(ecode, 1);
+
+ /* If this was a group that remembered the subject start, in order to break
+ infinite repeats of empty string matches, retrieve the subject start from
+ the chain. Otherwise, set it NULL. */
+
+ if (*prev >= OP_SBRA || *prev == OP_ONCE)
+ {
+ saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
+ eptrb = eptrb->epb_prev; /* Backup to previous group */
+ }
+ else saved_eptr = NULL;
+
+ /* If we are at the end of an assertion group or a non-capturing atomic
+ group, stop matching and return MATCH_MATCH, but record the current high
+ water mark for use by positive assertions. We also need to record the match
+ start in case it was changed by \K. */
+
+ if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
+ *prev == OP_ONCE_NC)
+ {
+ md->end_match_ptr = eptr; /* For ONCE_NC */
+ md->end_offset_top = offset_top;
+ md->start_match_ptr = mstart;
+ RRETURN(MATCH_MATCH); /* Sets md->mark */
+ }
+
+ /* For capturing groups we have to check the group number back at the start
+ and if necessary complete handling an extraction by setting the offsets and
+ bumping the high water mark. Whole-pattern recursion is coded as a recurse
+ into group 0, so it won't be picked up here. Instead, we catch it when the
+ OP_END is reached. Other recursion is handled here. We just have to record
+ the current subject position and start match pointer and give a MATCH
+ return. */
+
+ if (*prev == OP_CBRA || *prev == OP_SCBRA ||
+ *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
+ {
+ number = GET2(prev, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("end bracket %d", number);
+ printf("\n");
+#endif
+
+ /* Handle a recursively called group. */
+
+ if (md->recursive != NULL && md->recursive->group_num == number)
+ {
+ md->end_match_ptr = eptr;
+ md->start_match_ptr = mstart;
+ RRETURN(MATCH_MATCH);
+ }
+
+ /* Deal with capturing */
+
+ md->capture_last = number;
+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ {
+ /* If offset is greater than offset_top, it means that we are
+ "skipping" a capturing group, and that group's offsets must be marked
+ unset. In earlier versions of PCRE, all the offsets were unset at the
+ start of matching, but this doesn't work because atomic groups and
+ assertions can cause a value to be set that should later be unset.
+ Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
+ part of the atomic group, but this is not on the final matching path,
+ so must be unset when 2 is set. (If there is no group 2, there is no
+ problem, because offset_top will then be 2, indicating no capture.) */
+
+ if (offset > offset_top)
+ {
+ register int *iptr = md->offset_vector + offset_top;
+ register int *iend = md->offset_vector + offset;
+ while (iptr < iend) *iptr++ = -1;
+ }
+
+ /* Now make the extraction */
+
+ md->offset_vector[offset] =
+ md->offset_vector[md->offset_end - number];
+ md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
+ if (offset_top <= offset) offset_top = offset + 2;
+ }
+ }
+
+ /* For an ordinary non-repeating ket, just continue at this level. This
+ also happens for a repeating ket if no characters were matched in the
+ group. This is the forcible breaking of infinite loops as implemented in
+ Perl 5.005. For a non-repeating atomic group that includes captures,
+ establish a backup point by processing the rest of the pattern at a lower
+ level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
+ original OP_ONCE level, thereby bypassing intermediate backup points, but
+ resetting any captures that happened along the way. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE; /* Carry on at this level */
+ break;
+ }
+
+ /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
+ and return the MATCH_KETRPOS. This makes it possible to do the repeats one
+ at a time from the outer level, thus saving stack. */
+
+ if (*ecode == OP_KETRPOS)
+ {
+ md->end_match_ptr = eptr;
+ md->end_offset_top = offset_top;
+ RRETURN(MATCH_KETRPOS);
+ }
+
+ /* The normal repeating kets try the rest of the pattern or restart from
+ the preceding bracket, in the appropriate order. In the second case, we can
+ use tail recursion to avoid using another stack frame, unless we have an
+ an atomic group or an unlimited repeat of a group that can match an empty
+ string. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM8);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ if (*prev >= OP_SBRA) /* Could match an empty string */
+ {
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
+ RRETURN(rrc);
+ }
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
+ if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev;
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Not multiline mode: start of subject assertion, unless notbol. */
+
+ case OP_CIRC:
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+
+ /* Start of subject assertion */
+
+ case OP_SOD:
+ if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Multiline mode: start of subject unless notbol, or after any newline. */
+
+ case OP_CIRCM:
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+ if (eptr != md->start_subject &&
+ (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Start of match assertion */
+
+ case OP_SOM:
+ if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Reset the start of match point */
+
+ case OP_SET_SOM:
+ mstart = eptr;
+ ecode++;
+ break;
+
+ /* Multiline mode: assert before any newline, or before end of subject
+ unless noteol is set. */
+
+ case OP_DOLLM:
+ if (eptr < md->end_subject)
+ { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
+ else
+ {
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ }
+ ecode++;
+ break;
+
+ /* Not multiline mode: assert before a terminating newline or before end of
+ subject unless noteol is set. */
+
+ case OP_DOLL:
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ if (!md->endonly) goto ASSERT_NL_OR_EOS;
+
+ /* ... else fall through for endonly */
+
+ /* End of subject assertion (\z) */
+
+ case OP_EOD:
+ if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* End of subject or ending \n assertion (\Z) */
+
+ case OP_EODN:
+ ASSERT_NL_OR_EOS:
+ if (eptr < md->end_subject &&
+ (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
+ RRETURN(MATCH_NOMATCH);
+
+ /* Either at end of string or \n before end. */
+
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* Word boundary assertions */
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ {
+
+ /* Find out if the previous and current characters are "word" characters.
+ It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
+ be "non-word" characters. Remember the earliest consulted character for
+ partial matching. */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ /* Get status of previous character */
+
+ if (eptr == md->start_subject) prev_is_word = FALSE; else
+ {
+ PCRE_PUCHAR lastptr = eptr - 1;
+ BACKCHAR(lastptr);
+ if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
+ GETCHAR(c, lastptr);
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+ {
+ GETCHAR(c, eptr);
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+ }
+ }
+ else
+#endif
+
+ /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
+ consistency with the behaviour of \w we do use it in this case. */
+
+ {
+ /* Get status of previous character */
+
+ if (eptr == md->start_subject) prev_is_word = FALSE; else
+ {
+ if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ c = eptr[-1];
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ prev_is_word = MAX_255(eptr[-1])
+ && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ c = *eptr;
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ cur_is_word = MAX_255(*eptr)
+ && ((md->ctypes[*eptr] & ctype_word) != 0);
+ }
+
+ /* Now see if the situation is what we want */
+
+ if ((*ecode++ == OP_WORD_BOUNDARY)?
+ cur_is_word == prev_is_word : cur_is_word != prev_is_word)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Match a single character type; inline for speed */
+
+ case OP_ANY:
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ /* Fall through */
+
+ case OP_ALLANY:
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+#ifdef SUPPORT_UTF
+ if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+#endif
+ ecode++;
+ break;
+
+ /* Match a single byte, even in UTF-8 mode. This opcode really does match
+ any byte, even newline, independent of the setting of PCRE_DOTALL. */
+
+ case OP_ANYBYTE:
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ecode++;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_digit) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_DIGIT:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_digit) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_space) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WHITESPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_space) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_word) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WORDCHAR:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_word) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_ANYNL:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_HSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+ case OP_HSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_VSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+ case OP_VSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ ecode++;
+ break;
+
+#ifdef SUPPORT_UCP
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ {
+ const ucd_record *prop = GET_UCD(c);
+
+ switch(ecode[1])
+ {
+ case PT_ANY:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_GC:
+ if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_PC:
+ if ((ecode[2] != prop->chartype) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_SC:
+ if ((ecode[2] != prop->script) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_SPACE: /* Perl space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR)
+ == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* This should never occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ ecode += 3;
+ }
+ break;
+
+ /* Match an extended Unicode sequence. We will get here only if the support
+ is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_EXTUNI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ ecode++;
+ break;
+#endif
+
+
+ /* Match a back reference, possibly repeatedly. Look past the end of the
+ item to see if there is repeat information following. The code is similar
+ to that for character classes, but repeated for efficiency. Then obey
+ similar code to character type repeats - written out again for speed.
+ However, if the referenced string is the empty string, always treat
+ it as matched, any number of times (otherwise there could be infinite
+ loops). */
+
+ case OP_REF:
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
+
+ /* If the reference is unset, there are two possibilities:
+
+ (a) In the default, Perl-compatible state, set the length negative;
+ this ensures that every attempt at a match fails. We can't just fail
+ here, because of the possibility of quantifiers with zero minima.
+
+ (b) If the JavaScript compatibility flag is set, set the length to zero
+ so that the back reference matches an empty string.
+
+ Otherwise, set the length to the length of what was matched by the
+ referenced subpattern. */
+
+ if (offset >= offset_top || md->offset_vector[offset] < 0)
+ length = (md->jscript_compat)? 0 : -1;
+ else
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
+
+ /* Set up for repetition, or handle the non-repeated case */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += length;
+ continue; /* With the main loop */
+ }
+
+ /* Handle repeated back references. If the length of the reference is
+ zero, just continue with the main loop. If the length is negative, it
+ means the reference is unset in non-Java-compatible mode. If the minimum is
+ zero, we can continue at the same level without recursion. For any other
+ minimum, carrying on will result in NOMATCH. */
+
+ if (length == 0) continue;
+ if (length < 0 && min == 0) continue;
+
+ /* First, ensure the minimum number of matches are present. We get back
+ the length of the reference string explicitly rather than passing the
+ address of eptr, so that eptr can be a register variable. */
+
+ for (i = 1; i <= min; i++)
+ {
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+
+ /* If min = max, continue at the same level without recursion.
+ They are not both allowed to be zero. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep trying and advancing the pointer */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ int slength;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest string and work backwards */
+
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ break;
+ }
+ eptr += slength;
+ }
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr -= length;
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* Match a bit-mapped character class, possibly repeatedly. This op code is
+ used when all the characters in the class have values in the range 0-255,
+ and either the matching is caseful, or the characters are in the range
+ 0-127 when UTF-8 processing is enabled. The only difference between
+ OP_CLASS and OP_NCLASS occurs when a data character outside the range is
+ encountered.
+
+ First, look past the end of the item to see if there is repeat information
+ following. Then obey similar code to character type repeats - written out
+ again for speed. */
+
+ case OP_NCLASS:
+ case OP_CLASS:
+ {
+ /* The data variable is saved across frames, so the byte map needs to
+ be stored there. */
+#define BYTE_MAP ((pcre_uint8 *)data)
+ data = ecode + 1; /* Save for matching */
+ ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr += len;
+ }
+ for (;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr++;
+ }
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+#undef BYTE_MAP
+ }
+ /* Control never gets here */
+
+
+ /* Match an extended character class. This opcode is encountered only
+ when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
+ mode, because Unicode properties are supported in non-UTF-8 mode. */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ {
+ data = ecode + 1 + LINK_SIZE; /* Save for matching */
+ ecode += GET(ecode, 1); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+#ifdef SUPPORT_UTF
+ GETCHARLENTEST(c, eptr, len);
+#else
+ c = *eptr;
+#endif
+ if (!PRIV(xclass)(c, data, utf)) break;
+ eptr += len;
+ }
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+#ifdef SUPPORT_UTF
+ if (utf) BACKCHAR(eptr);
+#endif
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Control never gets here */
+ }
+#endif /* End of XCLASS */
+
+ /* Match a single character, casefully */
+
+ case OP_CHAR:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+ if (length > md->end_subject - eptr)
+ {
+ CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ if (md->end_subject - eptr < 1)
+ {
+ SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character, caselessly. If we are at the end of the
+ subject, give up immediately. */
+
+ case OP_CHARI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+
+ /* If the pattern character's value is < 128, we have only one byte, and
+ we know that its other case must also be one byte long, so we can use the
+ fast lookup table. We know that there is at least one byte left in the
+ subject. */
+
+ if (fc < 128)
+ {
+ if (md->lcc[fc]
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ eptr++;
+ }
+
+ /* Otherwise we must pick up the subject character. Note that we cannot
+ use the value of "length" to check for sufficient bytes left, because the
+ other case of the character may have more or fewer bytes. */
+
+ else
+ {
+ unsigned int dc;
+ GETCHARINC(dc, eptr);
+ ecode += length;
+
+ /* If we have Unicode property support, we can use it to test the other
+ case of the character, if there is one. */
+
+ if (fc != dc)
+ {
+#ifdef SUPPORT_UCP
+ if (dc != UCD_OTHERCASE(fc))
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(ecode[1], md->lcc, ecode[1])
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character repeatedly. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ possessive = TRUE;
+ /* Fall through */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-character matches. */
+
+ REPEATCHAR:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ charptr = ecode;
+ GETCHARLEN(fc, ecode, length);
+ ecode += length;
+
+ /* Handle multibyte character matching specially here. There is
+ support for caseless matching if UCP support is present. */
+
+ if (length > 1)
+ {
+#ifdef SUPPORT_UCP
+ unsigned int othercase;
+ if (op >= OP_STARI && /* Caseless */
+ (othercase = UCD_OTHERCASE(fc)) != fc)
+ oclength = PRIV(ord2utf)(othercase, occhars);
+ else oclength = 0;
+#endif /* SUPPORT_UCP */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ break;
+ }
+ }
+
+ if (possessive) continue;
+
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
+#ifdef SUPPORT_UCP
+ eptr--;
+ BACKCHAR(eptr);
+#else /* without SUPPORT_UCP */
+ eptr -= length;
+#endif /* SUPPORT_UCP */
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If the length of a UTF-8 character is 1, we fall through here, and
+ obey the code as for non-UTF-8 characters below, though in this case the
+ value of fc will always be < 128. */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* When not in UTF-8 mode, load a single-byte character. */
+ fc = *ecode++;
+
+ /* The value of fc at this point is always one character, though we may
+ or may not be in UTF mode. The code is duplicated for the caseless and
+ caseful cases, for speed, since matching characters is likely to be quite
+ common. First, ensure the minimum number of matches are present. If min =
+ max, continue at the same level without recursing. Otherwise, if
+ minimizing, keep trying the rest of the expression and advancing one
+ matching character if failing, up to the maximum. Alternatively, if
+ maximizing, find the maximum number of characters and work backwards. */
+
+ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+ max, eptr));
+
+ if (op >= OP_STARI) /* Caseless */
+ {
+#ifdef COMPILE_PCRE8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = md->fcc[fc];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
+#endif /* COMPILE_PCRE8 */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ if (min == max) continue;
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc != *eptr && foc != *eptr) break;
+ eptr++;
+ }
+
+ if (possessive) continue;
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* Caseful comparisons (includes all multi-byte characters) */
+
+ else
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc != *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a negated single one-byte character. The character we are
+ checking can be multibyte. */
+
+ case OP_NOT:
+ case OP_NOTI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ GETCHARINCTEST(c, eptr);
+ if (op == OP_NOTI) /* The caseless case */
+ {
+ register unsigned int ch, och;
+ ch = *ecode++;
+#ifdef COMPILE_PCRE8
+ /* ch must be < 128 if UTF is enabled. */
+ och = md->fcc[ch];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && ch > 127)
+ och = UCD_OTHERCASE(ch);
+#else
+ if (utf && ch > 127)
+ och = ch;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ och = TABLE_GET(ch, md->fcc, ch);
+#endif /* COMPILE_PCRE8 */
+ if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
+ }
+ else /* Caseful */
+ {
+ if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Match a negated single one-byte character repeatedly. This is almost a
+ repeat of the code for a repeated single character, but I haven't found a
+ nice way of commoning these up that doesn't require a test of the
+ positive/negative option for each character match. Maybe that wouldn't add
+ very much to the time taken, but character matching *is* what this is all
+ about... */
+
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-byte matches. */
+
+ REPEATNOTCHAR:
+ fc = *ecode++;
+
+ /* The code is duplicated for the caseless and caseful cases, for speed,
+ since matching characters is likely to be quite common. First, ensure the
+ minimum number of matches are present. If min = max, continue at the same
+ level without recursing. Otherwise, if minimizing, keep trying the rest of
+ the expression and advancing one matching character if failing, up to the
+ maximum. Alternatively, if maximizing, find the maximum number of
+ characters and work backwards. */
+
+ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+ max, eptr));
+
+ if (op >= OP_NOTSTARI) /* Caseless */
+ {
+#ifdef COMPILE_PCRE8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = md->fcc[fc];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
+#endif /* COMPILE_PCRE8 */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d || (unsigned int)foc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr || foc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* Caseful comparisons */
+
+ else
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a single character type repeatedly; several different opcodes
+ share code. This is very similar to the code for single characters, but we
+ repeat it in the interests of efficiency. */
+
+ case OP_TYPEEXACT:
+ min = max = GET2(ecode, 1);
+ minimize = TRUE;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_TYPEMINUPTO;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSSTAR:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSPLUS:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSQUERY:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSUPTO:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ c = *ecode++ - OP_TYPESTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single character type matches. Note that
+ in UTF-8 mode, '.' matches a character of any length, but for the other
+ character types, the valid characters are all one-byte long. */
+
+ REPEATTYPE:
+ ctype = *ecode++; /* Code for the character type */
+
+#ifdef SUPPORT_UCP
+ if (ctype == OP_PROP || ctype == OP_NOTPROP)
+ {
+ prop_fail_result = ctype == OP_NOTPROP;
+ prop_type = *ecode++;
+ prop_value = *ecode++;
+ }
+ else prop_type = -1;
+#endif
+
+ /* First, ensure the minimum number of matches are present. Use inline
+ code for maximizing the speed, and do the type test once at the start
+ (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
+ is tidier. Also separate the UCP code, which can be the same for both UTF-8
+ and single-bytes. */
+
+ if (min > 0)
+ {
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = 1; i <= min; i++)
+ {
+ int chartype;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_GC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_PC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_SC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_SPACE: /* Perl space */
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_WORD:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* This should not occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+/* Handle all other cases when the coding is UTF-8 */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ALLANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ } /* End switch(ctype) */
+
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Code for the non-UTF-8 case for minimum matching of operators other
+ than OP_PROP and OP_NOTPROP. */
+
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ if (eptr > md->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > md->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* If min = max, continue at the same level without recursing */
+
+ if (min == max) continue;
+
+ /* If minimizing, we have to test the rest of the pattern before each
+ subsequent match. Again, separate the UTF-8 case for speed, and also
+ separate the UCP cases. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_LAMP:
+ for (fi = min;; fi++)
+ {
+ int chartype;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_GC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_PC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_SC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_ALNUM:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_SPACE: /* Perl space */
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_PXSPACE: /* POSIX space */
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_WORD:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L ||
+ category == ucp_N ||
+ c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* This should never occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+ }
+ else
+#endif /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ GETCHARINC(c, eptr);
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ c = *eptr++;
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, it is worth using inline code for speed, doing the type
+ test once at the start (i.e. keep it out of the loop). Again, keep the
+ UTF-8 and UCP stuff separate. */
+
+ else
+ {
+ pp = eptr; /* Remember where we started */
+
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if (prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = min; i < max; i++)
+ {
+ int chartype;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_GC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_PC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_SC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_SPACE: /* Perl space */
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_WORD:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N ||
+ c == CHAR_UNDERSCORE) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ if (utf) BACKCHAR(eptr);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) == ucp_M) break;
+ eptr += len;
+ while (eptr < md->end_subject)
+ {
+ len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue;
+
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ for (;;) /* Move back over one extended */
+ {
+ if (!utf) c = *eptr; else
+ {
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr--;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ if (max < INT_MAX)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+
+ /* Handle unlimited UTF-8 repeat */
+
+ else
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+ break;
+
+ case OP_ALLANY:
+ if (max < INT_MAX)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+ else
+ {
+ eptr = md->end_subject; /* Unlimited UTF-8 repeat */
+ SCHECK_PARTIAL();
+ }
+ break;
+
+ /* The byte case is the same as non-UTF8 */
+
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (unsigned int)(md->end_subject - eptr))
+ {
+ eptr = md->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c == 0x000d)
+ {
+ if (++eptr >= md->end_subject) break;
+ if (*eptr == 0x000a) eptr++;
+ }
+ else
+ {
+ if (c != 0x000a &&
+ (md->bsr_anycrlf ||
+ (c != 0x000b && c != 0x000c &&
+ c != 0x0085 && c != 0x2028 && c != 0x2029)))
+ break;
+ eptr += len;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ default: gotspace = FALSE; break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ gotspace = TRUE;
+ break;
+ }
+ if (gotspace == (ctype == OP_NOT_HSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ default: gotspace = FALSE; break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ gotspace = TRUE;
+ break;
+ }
+ if (gotspace == (ctype == OP_NOT_VSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character, unless we are matching \R and the last thing matched was
+ \r\n, in which case, back up two bytes. */
+
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (unsigned int)(md->end_subject - eptr))
+ {
+ eptr = md->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x000d)
+ {
+ if (++eptr >= md->end_subject) break;
+ if (*eptr == 0x000a) eptr++;
+ }
+ else
+ {
+ if (c != 0x000a && (md->bsr_anycrlf ||
+ (c != 0x000b && c != 0x000c && c != 0x0085
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ))) break;
+ eptr++;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x09 || c == 0x20 || c == 0xa0
+#ifdef COMPILE_PCRE16
+ || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
+ || c == 0x202f || c == 0x205f || c == 0x3000
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c != 0x09 && c != 0x20 && c != 0xa0
+#ifdef COMPILE_PCRE16
+ && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
+ && c != 0x202f && c != 0x205f && c != 0x3000
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
+#ifdef COMPILE_PCRE16
+ || c == 0x2028 || c == 0x2029
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character (byte), unless we are matching \R and the last thing matched
+ was \r\n, in which case, back up two bytes. */
+
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
+ }
+ }
+
+ /* Get here if we can't make it match with any permitted repetitions */
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* There's been some horrible disaster. Arrival here can only mean there is
+ something seriously wrong in the code above or the OP_xxx definitions. */
+
+ default:
+ DPRINTF(("Unknown opcode %d\n", *ecode));
+ RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
+ }
+
+ /* Do not stick any code in here without much thought; it is assumed
+ that "continue" in the code above comes out to here to repeat the main
+ loop. */
+
+ } /* End of main loop */
+/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef NO_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+ {
+ LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
+ LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
+ LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
+ LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
+ LBL(65) LBL(66)
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ LBL(21)
+#endif
+#ifdef SUPPORT_UTF
+ LBL(16) LBL(18) LBL(20)
+ LBL(22) LBL(23) LBL(28) LBL(30)
+ LBL(32) LBL(34) LBL(42) LBL(46)
+#ifdef SUPPORT_UCP
+ LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
+ LBL(59) LBL(60) LBL(61) LBL(62)
+#endif /* SUPPORT_UCP */
+#endif /* SUPPORT_UTF */
+ default:
+ DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+
+printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
+
+ return PCRE_ERROR_INTERNAL;
+ }
+#undef LBL
+#endif /* NO_RECURSE */
+}
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+Undefine all the macros that were defined above to handle this. */
+
+#ifdef NO_RECURSE
+#undef eptr
+#undef ecode
+#undef mstart
+#undef offset_top
+#undef eptrb
+#undef flags
+
+#undef callpat
+#undef charptr
+#undef data
+#undef next
+#undef pp
+#undef prev
+#undef saved_eptr
+
+#undef new_recursive
+
+#undef cur_is_word
+#undef condition
+#undef prev_is_word
+
+#undef ctype
+#undef length
+#undef max
+#undef min
+#undef number
+#undef offset
+#undef op
+#undef save_capture_last
+#undef save_offset1
+#undef save_offset2
+#undef save_offset3
+#undef stacksave
+
+#undef newptrb
+
+#endif
+
+/* These two are defined as macros in both cases */
+
+#undef fc
+#undef fi
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+* Execute a Regular Expression *
+*************************************************/
+
+/* This function applies a compiled re to a subject string and picks out
+portions of the string if it matches. Two elements in the vector are set for
+each substring: the offsets to the start and end of the substring.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ offsets points to a vector of ints to be filled in with offsets
+ offsetcount the number of elements in the vector
+
+Returns: > 0 => success; value is the number of elements filled in
+ = 0 => success, but offsets is not big enough
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
+ PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount)
+#endif
+{
+int rc, ocount, arg_offset_max;
+int newline;
+BOOL using_temporary_offsets = FALSE;
+BOOL anchored;
+BOOL startline;
+BOOL firstline;
+BOOL utf;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
+match_data match_block;
+match_data *md = &match_block;
+const pcre_uint8 *tables;
+const pcre_uint8 *start_bits = NULL;
+PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
+PCRE_PUCHAR end_subject;
+PCRE_PUCHAR start_partial = NULL;
+PCRE_PUCHAR req_char_ptr = start_match - 1;
+
+const pcre_study_data *study;
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+
+/* Check for the special magic call that measures the size of the stack used
+per recursive call of match(). */
+
+if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
+ start_offset == -999)
+#ifdef NO_RECURSE
+ return -sizeof(heapframe);
+#else
+ return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
+#endif
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
+ return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* These two settings are used in the code for checking a UTF-8 string that
+follows immediately afterwards. Other values in the md block are used only
+during "normal" pcre_exec() processing, not when the JIT support is in use,
+so they are set up later. */
+
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = md->utf = (re->options & PCRE_UTF8) != 0;
+md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
+ ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
+
+/* Check a UTF-8 string if required. Pass back the character offset and error
+code for an invalid string if a results vector is available. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
+ {
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
+ if (errorcode != 0)
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+#ifdef COMPILE_PCRE16
+ return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
+#else
+ return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
+#endif
+ }
+
+ /* Check that a start_offset points to the start of a UTF character. */
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
+ }
+#endif
+
+/* If the pattern was successfully studied with JIT support, run the JIT
+executable instead of the rest of this function. Most options must be set at
+compile time for the JIT code to be usable. Fallback to the normal code path if
+an unsupported flag is set. In particular, JIT does not support partial
+matching. */
+
+#ifdef SUPPORT_JIT
+if (extra_data != NULL
+ && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0
+ && extra_data->executable_jit != NULL
+ && (extra_data->flags & PCRE_EXTRA_TABLES) == 0
+ && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
+ PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)
+ return PRIV(jit_exec)(re, extra_data->executable_jit,
+ (const pcre_uchar *)subject, length, start_offset, options,
+ ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
+ ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
+#endif
+
+/* Carry on with non-JIT matching. This information is for finding all the
+numbers associated with a given name, for condition testing. */
+
+md->name_table = (pcre_uchar *)re + re->name_table_offset;
+md->name_count = re->name_count;
+md->name_entry_size = re->name_entry_size;
+
+/* Fish out the optional data from the extra_data structure, first setting
+the default values. */
+
+study = NULL;
+md->match_limit = MATCH_LIMIT;
+md->match_limit_recursion = MATCH_LIMIT_RECURSION;
+md->callout_data = NULL;
+
+/* The table pointer is always in native byte order. */
+
+tables = re->tables;
+
+if (extra_data != NULL)
+ {
+ register unsigned int flags = extra_data->flags;
+ if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
+ md->match_limit = extra_data->match_limit;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+ md->match_limit_recursion = extra_data->match_limit_recursion;
+ if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+ md->callout_data = extra_data->callout_data;
+ if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
+ }
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (tables == NULL) tables = PRIV(default_tables);
+
+/* Set up other data */
+
+anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* The code starts after the real_pcre block and the capture name table. */
+
+md->start_code = (const pcre_uchar *)re + re->name_table_offset +
+ re->name_count * re->name_entry_size;
+
+md->start_subject = (PCRE_PUCHAR)subject;
+md->start_offset = start_offset;
+md->end_subject = md->start_subject + length;
+end_subject = md->end_subject;
+
+md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+md->use_ucp = (re->options & PCRE_UCP) != 0;
+md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+md->ignore_skip_arg = FALSE;
+
+/* Some options are unpacked into BOOL variables in the hope that testing
+them will be faster than individual option bits. */
+
+md->notbol = (options & PCRE_NOTBOL) != 0;
+md->noteol = (options & PCRE_NOTEOL) != 0;
+md->notempty = (options & PCRE_NOTEMPTY) != 0;
+md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+
+md->hitend = FALSE;
+md->mark = md->nomatch_mark = NULL; /* In case never set */
+
+md->recursive = NULL; /* No recursion at top level */
+md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
+
+md->lcc = tables + lcc_offset;
+md->fcc = tables + fcc_offset;
+md->ctypes = tables + ctypes_offset;
+
+/* Handle different \R options. */
+
+switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+ {
+ case 0:
+ if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+ md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
+ else
+#ifdef BSR_ANYCRLF
+ md->bsr_anycrlf = TRUE;
+#else
+ md->bsr_anycrlf = FALSE;
+#endif
+ break;
+
+ case PCRE_BSR_ANYCRLF:
+ md->bsr_anycrlf = TRUE;
+ break;
+
+ case PCRE_BSR_UNICODE:
+ md->bsr_anycrlf = FALSE;
+ break;
+
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
+ (pcre_uint32)options) & PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Compile-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+if (newline == -2)
+ {
+ md->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ md->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ md->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ md->nllen = 2;
+ md->nl[0] = (newline >> 8) & 255;
+ md->nl[1] = newline & 255;
+ }
+ else
+ {
+ md->nllen = 1;
+ md->nl[0] = newline;
+ }
+ }
+
+/* Partial matching was originally supported only for a restricted set of
+regexes; from release 8.00 there are no restrictions, but the bits are still
+defined (though never set). So there's no harm in leaving this code. */
+
+if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
+ return PCRE_ERROR_BADPARTIAL;
+
+/* If the expression has got more back references than the offsets supplied can
+hold, we get a temporary chunk of working store to use during the matching.
+Otherwise, we can use the vector supplied, rounding down its size to a multiple
+of 3. */
+
+ocount = offsetcount - (offsetcount % 3);
+arg_offset_max = (2*ocount)/3;
+
+if (re->top_backref > 0 && re->top_backref >= ocount/3)
+ {
+ ocount = re->top_backref * 3 + 3;
+ md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
+ if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
+ using_temporary_offsets = TRUE;
+ DPRINTF(("Got memory to hold back references\n"));
+ }
+else md->offset_vector = offsets;
+
+md->offset_end = ocount;
+md->offset_max = (2*ocount)/3;
+md->offset_overflow = FALSE;
+md->capture_last = -1;
+
+/* Reset the working variable associated with each extraction. These should
+never be used unless previously set, but they get saved and restored, and so we
+initialize them to avoid reading uninitialized locations. Also, unset the
+offsets for the matched string. This is really just for tidiness with callouts,
+in case they inspect these fields. */
+
+if (md->offset_vector != NULL)
+ {
+ register int *iptr = md->offset_vector + ocount;
+ register int *iend = iptr - re->top_bracket;
+ if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
+ while (--iptr >= iend) *iptr = -1;
+ md->offset_vector[0] = md->offset_vector[1] = -1;
+ }
+
+/* Set up the first character to match, if available. The first_char value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
+ }
+ else
+ if (!startline && study != NULL &&
+ (study->flags & PCRE_STUDY_MAPPED) != 0)
+ start_bits = study->start_bits;
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
+ }
+
+
+/* ==========================================================================*/
+
+/* Loop for handling unanchored repeated matching attempts; for anchored regexs
+the loop runs just once. */
+
+for(;;)
+ {
+ PCRE_PUCHAR save_end_subject = end_subject;
+ PCRE_PUCHAR new_start_match;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. That is, the match must be before or at the first
+ newline. Implement this by temporarily adjusting end_subject so that we stop
+ scanning at a newline. If the match fails at the newline, later code breaks
+ this loop. */
+
+ if (firstline)
+ {
+ PCRE_PUCHAR t = start_match;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (t < md->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found, or if a known later character is not present.
+ However, there is an option that disables these, for testing and for ensuring
+ that all callouts do actually occur. The option can be set in the regex by
+ (*NO_START_OPT) or passed in match-time options. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ /* Advance to a unique first char if there is one. */
+
+ if (has_first_char)
+ {
+ if (first_char != first_char2)
+ while (start_match < end_subject &&
+ *start_match != first_char && *start_match != first_char2)
+ start_match++;
+ else
+ while (start_match < end_subject && *start_match != first_char)
+ start_match++;
+ }
+
+ /* Or to just after a linebreak for a multiline match */
+
+ else if (startline)
+ {
+ if (start_match > md->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ {
+ start_match++;
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+ }
+ }
+ else
+#endif
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ start_match++;
+
+ /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
+ and we are now at a LF, advance the match position by one more character.
+ */
+
+ if (start_match[-1] == CHAR_CR &&
+ (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+ start_match < end_subject &&
+ *start_match == CHAR_NL)
+ start_match++;
+ }
+ }
+
+ /* Or to a non-unique first byte after study */
+
+ else if (start_bits != NULL)
+ {
+ while (start_match < end_subject)
+ {
+ register unsigned int c = *start_match;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) == 0)
+ {
+ start_match++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+#endif
+ }
+ else break;
+ }
+ }
+ } /* Starting optimizations */
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching or if
+ disabling is explicitly requested. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
+ {
+ /* If the pattern was studied, a minimum subject length may be set. This is
+ a lower bound; no actual string of that length may actually match the
+ pattern. Although the value is, strictly, in characters, we treat it as
+ bytes to avoid spending too much time in this optimization. */
+
+ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+ (pcre_uint32)(end_subject - start_match) < study->minlength)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
+ must be later in the subject; otherwise the test starts at the match point.
+ This optimization can save a huge amount of backtracking in patterns with
+ nested unlimited repeats that aren't going to match. Writing separate code
+ for cased/caseless versions makes it go faster, as does using an
+ autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary patterns.
+ This showed up when somebody was matching something like /^\d+C/ on a
+ 32-megabyte string... so we don't do this when the string is sufficiently
+ long. */
+
+ if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
+ {
+ register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_char_ptr)
+ {
+ if (req_char != req_char2)
+ {
+ while (p < end_subject)
+ {
+ register int pp = *p++;
+ if (pp == req_char || pp == req_char2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (*p++ == req_char) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required character, break the matching loop,
+ forcing a match failure. */
+
+ if (p >= end_subject)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If we have found the required character, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this character yet. */
+
+ req_char_ptr = p;
+ }
+ }
+ }
+
+#ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */
+ printf(">>>> Match against: ");
+ pchars(start_match, end_subject - start_match, TRUE, md);
+ printf("\n");
+#endif
+
+ /* OK, we can now run the match. If "hitend" is set afterwards, remember the
+ first starting point for which a partial match was found. */
+
+ md->start_match_ptr = start_match;
+ md->start_used_ptr = start_match;
+ md->match_call_count = 0;
+ md->match_function_type = 0;
+ md->end_offset_top = 0;
+ rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
+ if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
+
+ switch(rc)
+ {
+ /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
+ the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
+ entirely. The only way we can do that is to re-do the match at the same
+ point, with a flag to force SKIP with an argument to be ignored. Just
+ treating this case as NOMATCH does not work because it does not check other
+ alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
+
+ case MATCH_SKIP_ARG:
+ new_start_match = start_match;
+ md->ignore_skip_arg = TRUE;
+ break;
+
+ /* SKIP passes back the next starting point explicitly, but if it is the
+ same as the match we have just done, treat it as NOMATCH. */
+
+ case MATCH_SKIP:
+ if (md->start_match_ptr != start_match)
+ {
+ new_start_match = md->start_match_ptr;
+ break;
+ }
+ /* Fall through */
+
+ /* NOMATCH and PRUNE advance by one character. THEN at this level acts
+ exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
+
+ case MATCH_NOMATCH:
+ case MATCH_PRUNE:
+ case MATCH_THEN:
+ md->ignore_skip_arg = FALSE;
+ new_start_match = start_match + 1;
+#ifdef SUPPORT_UTF
+ if (utf)
+ ACROSSCHAR(new_start_match < end_subject, *new_start_match,
+ new_start_match++);
+#endif
+ break;
+
+ /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
+
+ case MATCH_COMMIT:
+ rc = MATCH_NOMATCH;
+ goto ENDLOOP;
+
+ /* Any other return is either a match, or some kind of error. */
+
+ default:
+ goto ENDLOOP;
+ }
+
+ /* Control reaches here for the various types of "no match at this point"
+ result. Reset the code to MATCH_NOMATCH for subsequent checking. */
+
+ rc = MATCH_NOMATCH;
+
+ /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
+ newline in the subject (though it may continue over the newline). Therefore,
+ if we have just failed to match, starting at a newline, do not continue. */
+
+ if (firstline && IS_NEWLINE(start_match)) break;
+
+ /* Advance to new matching position */
+
+ start_match = new_start_match;
+
+ /* Break the loop if the pattern is anchored or if we have passed the end of
+ the subject. */
+
+ if (anchored || start_match > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more character. In
+ normal matching start_match will aways be greater than the first position at
+ this stage, but a failed *SKIP can cause a return at the same point, which is
+ why the first test exists. */
+
+ if (start_match > (PCRE_PUCHAR)subject + start_offset &&
+ start_match[-1] == CHAR_CR &&
+ start_match < end_subject &&
+ *start_match == CHAR_NL &&
+ (re->flags & PCRE_HASCRORLF) == 0 &&
+ (md->nltype == NLTYPE_ANY ||
+ md->nltype == NLTYPE_ANYCRLF ||
+ md->nllen == 2))
+ start_match++;
+
+ md->mark = NULL; /* Reset for start of next match attempt */
+ } /* End of for(;;) "bumpalong" loop */
+
+/* ==========================================================================*/
+
+/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
+conditions is true:
+
+(1) The pattern is anchored or the match was failed by (*COMMIT);
+
+(2) We are past the end of the subject;
+
+(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
+ this option requests that a match occur at or before the first newline in
+ the subject.
+
+When we have a match and the offset vector is big enough to deal with any
+backreferences, captured substring offsets will already be set up. In the case
+where we had to get some local store to hold offsets for backreference
+processing, copy those that we can. In this case there need not be overflow if
+certain parts of the pattern were not used, even though there are more
+capturing parentheses than vector slots. */
+
+ENDLOOP:
+
+if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
+ {
+ if (using_temporary_offsets)
+ {
+ if (arg_offset_max >= 4)
+ {
+ memcpy(offsets + 2, md->offset_vector + 2,
+ (arg_offset_max - 2) * sizeof(int));
+ DPRINTF(("Copied offsets from temporary memory\n"));
+ }
+ if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
+ DPRINTF(("Freeing temporary memory\n"));
+ (PUBL(free))(md->offset_vector);
+ }
+
+ /* Set the return code to the number of captured strings, or 0 if there were
+ too many to fit into the vector. */
+
+ rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?
+ 0 : md->end_offset_top/2;
+
+ /* If there is space in the offset vector, set any unused pairs at the end of
+ the pattern to -1 for backwards compatibility. It is documented that this
+ happens. In earlier versions, the whole set of potential capturing offsets
+ was set to -1 each time round the loop, but this is handled differently now.
+ "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only
+ those at the end that need unsetting here. We can't just unset them all at
+ the start of the whole thing because they may get set in one branch that is
+ not the final matching branch. */
+
+ if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL)
+ {
+ register int *iptr, *iend;
+ int resetcount = 2 + re->top_bracket * 2;
+ if (resetcount > offsetcount) resetcount = ocount;
+ iptr = offsets + md->end_offset_top;
+ iend = offsets + resetcount;
+ while (iptr < iend) *iptr++ = -1;
+ }
+
+ /* If there is space, set up the whole thing as substring 0. The value of
+ md->start_match_ptr might be modified if \K was encountered on the success
+ matching path. */
+
+ if (offsetcount < 2) rc = 0; else
+ {
+ offsets[0] = (int)(md->start_match_ptr - md->start_subject);
+ offsets[1] = (int)(md->end_match_ptr - md->start_subject);
+ }
+
+ /* Return MARK data if requested */
+
+ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = (pcre_uchar *)md->mark;
+ DPRINTF((">>>> returning %d\n", rc));
+ return rc;
+ }
+
+/* Control gets here if there has been an error, or if the overall match
+attempt has failed at all permitted starting positions. */
+
+if (using_temporary_offsets)
+ {
+ DPRINTF(("Freeing temporary memory\n"));
+ (PUBL(free))(md->offset_vector);
+ }
+
+/* For anything other than nomatch or partial match, just return the code. */
+
+if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
+ {
+ DPRINTF((">>>> error: returning %d\n", rc));
+ return rc;
+ }
+
+/* Handle partial matches - disable any mark data */
+
+if (start_partial != NULL)
+ {
+ DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
+ md->mark = NULL;
+ if (offsetcount > 1)
+ {
+ offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
+ offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
+ }
+ rc = PCRE_ERROR_PARTIAL;
+ }
+
+/* This is the classic nomatch case */
+
+else
+ {
+ DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
+ rc = PCRE_ERROR_NOMATCH;
+ }
+
+/* Return the MARK data if it has been requested. */
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
+return rc;
+}
+
+/* End of pcre_exec.c */
diff --git a/src/3rdparty/pcre/pcre_fullinfo.c b/src/3rdparty/pcre/pcre_fullinfo.c
new file mode 100644
index 0000000000..e5e68f3f29
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_fullinfo.c
@@ -0,0 +1,202 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_fullinfo(), which returns
+information about a compiled pattern. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return info about compiled pattern *
+*************************************************/
+
+/* This is a newer "info" function which has an extensible interface so
+that additional items can be added compatibly.
+
+Arguments:
+ argument_re points to compiled code
+ extra_data points extra data, or NULL
+ what what information is required
+ where where to put the information
+
+Returns: 0 if data returned, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
+ int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ int what, void *where)
+#endif
+{
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+const pcre_study_data *study = NULL;
+
+if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+
+/* Check that this pattern was compiled in the correct bit mode */
+
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+switch (what)
+ {
+ case PCRE_INFO_OPTIONS:
+ *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
+ break;
+
+ case PCRE_INFO_SIZE:
+ *((size_t *)where) = re->size;
+ break;
+
+ case PCRE_INFO_STUDYSIZE:
+ *((size_t *)where) = (study == NULL)? 0 : study->size;
+ break;
+
+ case PCRE_INFO_JITSIZE:
+#ifdef SUPPORT_JIT
+ *((size_t *)where) =
+ (extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL)?
+ PRIV(jit_get_size)(extra_data->executable_jit) : 0;
+#else
+ *((size_t *)where) = 0;
+#endif
+ break;
+
+ case PCRE_INFO_CAPTURECOUNT:
+ *((int *)where) = re->top_bracket;
+ break;
+
+ case PCRE_INFO_BACKREFMAX:
+ *((int *)where) = re->top_backref;
+ break;
+
+ case PCRE_INFO_FIRSTBYTE:
+ *((int *)where) =
+ ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char :
+ ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
+ break;
+
+ /* Make sure we pass back the pointer to the bit vector in the external
+ block, not the internal copy (with flipped integer fields). */
+
+ case PCRE_INFO_FIRSTTABLE:
+ *((const pcre_uint8 **)where) =
+ (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
+ ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
+ break;
+
+ case PCRE_INFO_MINLENGTH:
+ *((int *)where) =
+ (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
+ (int)(study->minlength) : -1;
+ break;
+
+ case PCRE_INFO_JIT:
+ *((int *)where) = extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL;
+ break;
+
+ case PCRE_INFO_LASTLITERAL:
+ *((int *)where) =
+ ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1;
+ break;
+
+ case PCRE_INFO_NAMEENTRYSIZE:
+ *((int *)where) = re->name_entry_size;
+ break;
+
+ case PCRE_INFO_NAMECOUNT:
+ *((int *)where) = re->name_count;
+ break;
+
+ case PCRE_INFO_NAMETABLE:
+ *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
+ break;
+
+ case PCRE_INFO_DEFAULT_TABLES:
+ *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
+ break;
+
+ /* From release 8.00 this will always return TRUE because NOPARTIAL is
+ no longer ever set (the restrictions have been removed). */
+
+ case PCRE_INFO_OKPARTIAL:
+ *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
+ break;
+
+ case PCRE_INFO_JCHANGED:
+ *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
+ break;
+
+ case PCRE_INFO_HASCRORLF:
+ *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
+ break;
+
+ default: return PCRE_ERROR_BADOPTION;
+ }
+
+return 0;
+}
+
+/* End of pcre_fullinfo.c */
diff --git a/src/3rdparty/pcre/pcre_get.c b/src/3rdparty/pcre/pcre_get.c
new file mode 100644
index 0000000000..daecb695fe
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_get.c
@@ -0,0 +1,587 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains some convenience functions for extracting substrings
+from the subject string after a regex match has succeeded. The original idea
+for these functions came from Scott Wimer. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Find number for named string *
+*************************************************/
+
+/* This function is used by the get_first_set() function below, as well
+as being generally available. It assumes that names are unique.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose number is required
+
+Returns: the number of the named parentheses, or a negative number
+ (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringnumber(const pcre *code, const char *stringname)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
+#endif
+{
+int rc;
+int entrysize;
+int top, bot;
+pcre_uchar *nametable;
+
+#ifdef COMPILE_PCRE8
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+
+bot = 0;
+while (top > bot)
+ {
+ int mid = (top + bot) / 2;
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
+ if (c == 0) return GET2(entry, 0);
+ if (c > 0) bot = mid + 1; else top = mid;
+ }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+* Find (multiple) entries for named string *
+*************************************************/
+
+/* This is used by the get_first_set() function below, as well as being
+generally available. It is used when duplicated names are permitted.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose entries required
+ firstptr where to put the pointer to the first entry
+ lastptr where to put the pointer to the last entry
+
+Returns: the length of each entry, or a negative number
+ (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringtable_entries(const pcre *code, const char *stringname,
+ char **firstptr, char **lastptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
+#endif
+{
+int rc;
+int entrysize;
+int top, bot;
+pcre_uchar *nametable, *lastentry;
+
+#ifdef COMPILE_PCRE8
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+
+lastentry = nametable + entrysize * (top - 1);
+bot = 0;
+while (top > bot)
+ {
+ int mid = (top + bot) / 2;
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
+ if (c == 0)
+ {
+ pcre_uchar *first = entry;
+ pcre_uchar *last = entry;
+ while (first > nametable)
+ {
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
+ first -= entrysize;
+ }
+ while (last < lastentry)
+ {
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
+ last += entrysize;
+ }
+#ifdef COMPILE_PCRE8
+ *firstptr = (char *)first;
+ *lastptr = (char *)last;
+#else
+ *firstptr = (PCRE_UCHAR16 *)first;
+ *lastptr = (PCRE_UCHAR16 *)last;
+#endif
+ return entrysize;
+ }
+ if (c > 0) bot = mid + 1; else top = mid;
+ }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+* Find first set of multiple named strings *
+*************************************************/
+
+/* This function allows for duplicate names in the table of named substrings.
+It returns the number of the first one that was set in a pattern match.
+
+Arguments:
+ code the compiled regex
+ stringname the name of the capturing substring
+ ovector the vector of matched substrings
+
+Returns: the number of the first that is set,
+ or the number of the last one if none are set,
+ or a negative number on error
+*/
+
+#ifdef COMPILE_PCRE8
+static int
+get_first_set(const pcre *code, const char *stringname, int *ovector)
+#else
+static int
+get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector)
+#endif
+{
+const REAL_PCRE *re = (const REAL_PCRE *)code;
+int entrysize;
+pcre_uchar *entry;
+#ifdef COMPILE_PCRE8
+char *first, *last;
+#else
+PCRE_UCHAR16 *first, *last;
+#endif
+
+#ifdef COMPILE_PCRE8
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+ return pcre_get_stringnumber(code, stringname);
+entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
+#else
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+ return pcre16_get_stringnumber(code, stringname);
+entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
+#endif
+if (entrysize <= 0) return entrysize;
+for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
+ {
+ int n = GET2(entry, 0);
+ if (ovector[n*2] >= 0) return n;
+ }
+return GET2(entry, 0);
+}
+
+
+
+
+/*************************************************
+* Copy captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer.
+Note that we use memcpy() rather than strncpy() in case there are binary zeros
+in the string.
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringnumber the number of the required substring
+ buffer where to put the substring
+ size the size of the buffer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) buffer too small
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_substring(const char *subject, int *ovector, int stringcount,
+ int stringnumber, char *buffer, int size)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_UCHAR16 *buffer, int size)
+#endif
+{
+int yield;
+if (stringnumber < 0 || stringnumber >= stringcount)
+ return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
+memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
+buffer[yield] = 0;
+return yield;
+}
+
+
+
+/*************************************************
+* Copy named captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer,
+identifying it by name. If the regex permits duplicate names, the first
+substring that is set is chosen.
+
+Arguments:
+ code the compiled regex
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringname the name of the required substring
+ buffer where to put the substring
+ size the size of the buffer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) buffer too small
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ char *buffer, int size)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 *buffer, int size)
+#endif
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
+return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#else
+return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#endif
+}
+
+
+
+/*************************************************
+* Copy all captured strings to new store *
+*************************************************/
+
+/* This function gets one chunk of store and builds a list of pointers and all
+of the captured substrings in it. A NULL pointer is put on the end of the list.
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ listptr set to point to the list of pointers
+
+Returns: if successful: 0
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) failed to get store
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
+ const char ***listptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ PCRE_SPTR16 **listptr)
+#endif
+{
+int i;
+int size = sizeof(pcre_uchar *);
+int double_count = stringcount * 2;
+pcre_uchar **stringlist;
+pcre_uchar *p;
+
+for (i = 0; i < double_count; i += 2)
+ size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1);
+
+stringlist = (pcre_uchar **)(PUBL(malloc))(size);
+if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
+
+#ifdef COMPILE_PCRE8
+*listptr = (const char **)stringlist;
+#else
+*listptr = (PCRE_SPTR16 *)stringlist;
+#endif
+p = (pcre_uchar *)(stringlist + stringcount + 1);
+
+for (i = 0; i < double_count; i += 2)
+ {
+ int len = ovector[i+1] - ovector[i];
+ memcpy(p, subject + ovector[i], IN_UCHARS(len));
+ *stringlist++ = p;
+ p += len;
+ *p++ = 0;
+ }
+
+*stringlist = NULL;
+return 0;
+}
+
+
+
+/*************************************************
+* Free store obtained by get_substring_list *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
+
+Argument: the result of a previous pcre_get_substring_list()
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring_list(const char **pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring_list(PCRE_SPTR16 *pointer)
+#endif
+{
+(PUBL(free))((void *)pointer);
+}
+
+
+
+/*************************************************
+* Copy captured string to new store *
+*************************************************/
+
+/* This function copies a single captured substring into a piece of new
+store
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringnumber the number of the required substring
+ stringptr where to put a pointer to the substring
+
+Returns: if successful:
+ the length of the string, not including the zero that
+ is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) failed to get store
+ PCRE_ERROR_NOSUBSTRING (-7) substring not present
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring(const char *subject, int *ovector, int stringcount,
+ int stringnumber, const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_SPTR16 *stringptr)
+#endif
+{
+int yield;
+pcre_uchar *substring;
+if (stringnumber < 0 || stringnumber >= stringcount)
+ return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
+if (substring == NULL) return PCRE_ERROR_NOMEMORY;
+memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
+substring[yield] = 0;
+#ifdef COMPILE_PCRE8
+*stringptr = (const char *)substring;
+#else
+*stringptr = (PCRE_SPTR16)substring;
+#endif
+return yield;
+}
+
+
+
+/*************************************************
+* Copy named captured string to new store *
+*************************************************/
+
+/* This function copies a single captured substring, identified by name, into
+new store. If the regex permits duplicate names, the first substring that is
+set is chosen.
+
+Arguments:
+ code the compiled regex
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringname the name of the required substring
+ stringptr where to put the pointer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) couldn't get memory
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_SPTR16 *stringptr)
+#endif
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
+return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
+#else
+return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
+#endif
+}
+
+
+
+
+/*************************************************
+* Free store obtained by get_substring *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
+
+Argument: the result of a previous pcre_get_substring()
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring(const char *pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring(PCRE_SPTR16 pointer)
+#endif
+{
+(PUBL(free))((void *)pointer);
+}
+
+/* End of pcre_get.c */
diff --git a/src/3rdparty/pcre/pcre_globals.c b/src/3rdparty/pcre/pcre_globals.c
new file mode 100644
index 0000000000..d5b6286fc2
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_globals.c
@@ -0,0 +1,84 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains global variables that are exported by the PCRE library.
+PCRE is thread-clean and doesn't use any global variables in the normal sense.
+However, it calls memory allocation and freeing functions via the four
+indirections below, and it can optionally do callouts, using the fifth
+indirection. These values can be changed by the caller, but are shared between
+all threads.
+
+For MS Visual Studio and Symbian OS, there are problems in initializing these
+variables to non-local functions. In these cases, therefore, an indirection via
+a local function is used.
+
+Also, when compiling for Virtual Pascal, things are done differently, and
+global variables are not used. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#if defined _MSC_VER || defined __SYMBIAN32__
+static void* LocalPcreMalloc(size_t aSize)
+ {
+ return malloc(aSize);
+ }
+static void LocalPcreFree(void* aPtr)
+ {
+ free(aPtr);
+ }
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
+
+#elif !defined VPCOMPAT
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
+#endif
+
+/* End of pcre_globals.c */
diff --git a/src/3rdparty/pcre/pcre_internal.h b/src/3rdparty/pcre/pcre_internal.h
new file mode 100644
index 0000000000..e5a4b6a526
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_internal.h
@@ -0,0 +1,2332 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This header contains definitions that are shared between the different
+modules, but which are not relevant to the exported API. This includes some
+functions whose names all begin with "_pcre_" or "_pcre16_" depending on
+the PRIV macro. */
+
+#ifndef PCRE_INTERNAL_H
+#define PCRE_INTERNAL_H
+
+/* Define PCRE_DEBUG to get debugging output on stdout. */
+
+#if 0
+#define PCRE_DEBUG
+#endif
+
+/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */
+#ifndef COMPILE_PCRE16
+#define COMPILE_PCRE8
+#endif
+
+/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
+"configure" script ensures this, but not everybody uses "configure". */
+
+#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
+reasons with existing code. */
+
+#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
+Until then we define it if SUPPORT_UTF is defined. */
+
+#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
+#define SUPPORT_UTF8 1
+#endif
+
+/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure"
+script prevents both being selected, but not everybody uses "configure". */
+
+#if defined EBCDIC && defined SUPPORT_UTF
+#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported.
+#endif
+
+/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
+inline, and there are *still* stupid compilers about that don't like indented
+pre-processor statements, or at least there were when I first wrote this. After
+all, it had only been about 10 years then...
+
+It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
+be absolutely sure we get our version. */
+
+#undef DPRINTF
+#ifdef PCRE_DEBUG
+#define DPRINTF(p) printf p
+#else
+#define DPRINTF(p) /* Nothing */
+#endif
+
+
+/* Standard C headers plus the external interface definition. The only time
+setjmp and stdarg are used is when NO_RECURSE is set. */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* When compiling a DLL for Windows, the exported symbols have to be declared
+using some MS magic. I found some useful information on this web page:
+http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
+information there, using __declspec(dllexport) without "extern" we have a
+definition; with "extern" we have a declaration. The settings here override the
+setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
+which is all that is needed for applications (they just import the symbols). We
+use:
+
+ PCRE_EXP_DECL for declarations
+ PCRE_EXP_DEFN for definitions of exported functions
+ PCRE_EXP_DATA_DEFN for definitions of exported variables
+
+The reason for the two DEFN macros is that in non-Windows environments, one
+does not want to have "extern" before variable definitions because it leads to
+compiler warnings. So we distinguish between functions and variables. In
+Windows, the two should always be the same.
+
+The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
+which is an application, but needs to import this file in order to "peek" at
+internals, can #include pcre.h first to get an application's-eye view.
+
+In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
+special-purpose environments) might want to stick other stuff in front of
+exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
+PCRE_EXP_DATA_DEFN only if they are not already set. */
+
+#ifndef PCRE_EXP_DECL
+# ifdef _WIN32
+# ifndef PCRE_STATIC
+# define PCRE_EXP_DECL extern __declspec(dllexport)
+# define PCRE_EXP_DEFN __declspec(dllexport)
+# define PCRE_EXP_DATA_DEFN __declspec(dllexport)
+# else
+# define PCRE_EXP_DECL extern
+# define PCRE_EXP_DEFN
+# define PCRE_EXP_DATA_DEFN
+# endif
+# else
+# ifdef __cplusplus
+# define PCRE_EXP_DECL extern "C"
+# else
+# define PCRE_EXP_DECL extern
+# endif
+# ifndef PCRE_EXP_DEFN
+# define PCRE_EXP_DEFN PCRE_EXP_DECL
+# endif
+# ifndef PCRE_EXP_DATA_DEFN
+# define PCRE_EXP_DATA_DEFN
+# endif
+# endif
+#endif
+
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+ void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE_CALL_CONVENTION
+#define PCRE_CALL_CONVENTION
+#endif
+
+/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
+cannot determine these outside the compilation (e.g. by running a program as
+part of "configure") because PCRE is often cross-compiled for use on other
+systems. Instead we make use of the maximum sizes that are available at
+preprocessor time in standard C environments. */
+
+typedef unsigned char pcre_uint8;
+
+#if USHRT_MAX == 65535
+ typedef unsigned short pcre_uint16;
+ typedef short pcre_int16;
+#elif UINT_MAX == 65535
+ typedef unsigned int pcre_uint16;
+ typedef int pcre_int16;
+#else
+ #error Cannot determine a type for 16-bit unsigned integers
+#endif
+
+#if UINT_MAX == 4294967295
+ typedef unsigned int pcre_uint32;
+ typedef int pcre_int32;
+#elif ULONG_MAX == 4294967295
+ typedef unsigned long int pcre_uint32;
+ typedef long int pcre_int32;
+#else
+ #error Cannot determine a type for 32-bit unsigned integers
+#endif
+
+/* When checking for integer overflow in pcre_compile(), we need to handle
+large integers. If a 64-bit integer type is available, we can use that.
+Otherwise we have to cast to double, which of course requires floating point
+arithmetic. Handle this by defining a macro for the appropriate type. If
+stdint.h is available, include it; it may define INT64_MAX. Systems that do not
+have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
+by "configure". */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if defined INT64_MAX || defined int64_t
+#define INT64_OR_DOUBLE int64_t
+#else
+#define INT64_OR_DOUBLE double
+#endif
+
+/* All character handling must be done as unsigned characters. Otherwise there
+are problems with top-bit-set characters and functions such as isspace().
+However, we leave the interface to the outside world as char * or short *,
+because that should make things easier for callers. This character type is
+called pcre_uchar.
+
+The IN_UCHARS macro multiply its argument with the byte size of the current
+pcre_uchar type. Useful for memcpy and such operations, whose require the
+byte size of their input/output buffers.
+
+The MAX_255 macro checks whether its pcre_uchar input is less than 256.
+
+The TABLE_GET macro is designed for accessing elements of tables whose contain
+exactly 256 items. When the character is able to contain more than 256
+items, some check is needed before accessing these tables.
+*/
+
+#ifdef COMPILE_PCRE8
+
+typedef unsigned char pcre_uchar;
+#define IN_UCHARS(x) (x)
+#define MAX_255(c) 1
+#define TABLE_GET(c, table, default) ((table)[c])
+
+#else
+
+#ifdef COMPILE_PCRE16
+#if USHRT_MAX != 65535
+/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
+pcre.h(.in) and disable (comment out) this message. */
+#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
+#endif
+
+typedef pcre_uint16 pcre_uchar;
+#define IN_UCHARS(x) ((x) << 1)
+#define MAX_255(c) ((c) <= 255u)
+#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+/* This is an unsigned int value that no character can ever have. UTF-8
+characters only go up to 0x7fffffff (though Unicode doesn't go beyond
+0x0010ffff). */
+
+#define NOTACHAR 0xffffffff
+
+/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
+"any" and "anycrlf" at present). The following macros are used to package up
+testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
+modules to indicate in which datablock the parameters exist, and what the
+start/end of string field names are. */
+
+#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
+#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
+#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
+
+/* This macro checks for a newline at the given position */
+
+#define IS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) < NLBLOCK->PSEND && \
+ PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
+ (p)[0] == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* This macro checks for a newline immediately preceding the given position */
+
+#define WAS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) > NLBLOCK->PSSTART && \
+ PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
+ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
+with a custom type. This makes it possible, for example, to allow pcre_exec()
+to process subject strings that are discontinuous by using a smart pointer
+class. It must always be possible to inspect all of the subject string in
+pcre_exec() because of the way it backtracks. Two macros are required in the
+normal case, for sign-unspecified and unsigned char pointers. The former is
+used for the external interface and appears in pcre.h, which is why its name
+must begin with PCRE_. */
+
+#ifdef CUSTOM_SUBJECT_PTR
+#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
+#else
+#define PCRE_PUCHAR const pcre_uchar *
+#endif
+
+/* Include the public PCRE header and the definitions of UCP character property
+values. */
+
+#include "pcre.h"
+#include "ucp.h"
+
+/* When compiling for use with the Virtual Pascal compiler, these functions
+need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
+option on the command line. */
+
+#ifdef VPCOMPAT
+#define strlen(s) _strlen(s)
+#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
+#define memcmp(s,c,n) _memcmp(s,c,n)
+#define memcpy(d,s,n) _memcpy(d,s,n)
+#define memmove(d,s,n) _memmove(d,s,n)
+#define memset(s,c,n) _memset(s,c,n)
+#else /* VPCOMPAT */
+
+/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). */
+
+#ifndef HAVE_MEMMOVE
+#undef memmove /* some systems may have a macro */
+#ifdef HAVE_BCOPY
+#define memmove(a, b, c) bcopy(b, a, c)
+#else /* HAVE_BCOPY */
+static void *
+pcre_memmove(void *d, const void *s, size_t n)
+{
+size_t i;
+unsigned char *dest = (unsigned char *)d;
+const unsigned char *src = (const unsigned char *)s;
+if (dest > src)
+ {
+ dest += n;
+ src += n;
+ for (i = 0; i < n; ++i) *(--dest) = *(--src);
+ return (void *)dest;
+ }
+else
+ {
+ for (i = 0; i < n; ++i) *dest++ = *src++;
+ return (void *)(dest - n);
+ }
+}
+#define memmove(a, b, c) pcre_memmove(a, b, c)
+#endif /* not HAVE_BCOPY */
+#endif /* not HAVE_MEMMOVE */
+#endif /* not VPCOMPAT */
+
+
+/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
+in big-endian order) by default. These are used, for example, to link from the
+start of a subpattern to its alternatives and its end. The use of 2 bytes per
+offset limits the size of the compiled regex to around 64K, which is big enough
+for almost everybody. However, I received a request for an even bigger limit.
+For this reason, and also to make the code easier to maintain, the storing and
+loading of offsets from the byte string is now handled by the macros that are
+defined here.
+
+The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
+the config.h file, but can be overridden by using -D on the command line. This
+is automated on Unix systems via the "configure" command. */
+
+#ifdef COMPILE_PCRE8
+
+#if LINK_SIZE == 2
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 8), \
+ (a[(n)+1] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 8) | (a)[(n)+1])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+
+#elif LINK_SIZE == 3
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 16), \
+ (a[(n)+1] = (d) >> 8), \
+ (a[(n)+2] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
+
+#define MAX_PATTERN_SIZE (1 << 24)
+
+
+#elif LINK_SIZE == 4
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 24), \
+ (a[(n)+1] = (d) >> 16), \
+ (a[(n)+2] = (d) >> 8), \
+ (a[(n)+3] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
+
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#if LINK_SIZE == 2
+
+#undef LINK_SIZE
+#define LINK_SIZE 1
+
+#define PUT(a,n,d) \
+ (a[n] = (d))
+
+#define GET(a,n) \
+ (a[n])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+#elif LINK_SIZE == 3 || LINK_SIZE == 4
+
+#undef LINK_SIZE
+#define LINK_SIZE 2
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 16), \
+ (a[(n)+1] = (d) & 65535)
+
+#define GET(a,n) \
+ (((a)[n] << 16) | (a)[(n)+1])
+
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+/* Convenience macro defined in terms of the others */
+
+#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
+
+
+/* PCRE uses some other 2-byte quantities that do not change when the size of
+offsets changes. There are used for repeat counts and for other things such as
+capturing parenthesis numbers in back references. */
+
+#ifdef COMPILE_PCRE8
+
+#define IMM2_SIZE 2
+
+#define PUT2(a,n,d) \
+ a[n] = (d) >> 8; \
+ a[(n)+1] = (d) & 255
+
+#define GET2(a,n) \
+ (((a)[n] << 8) | (a)[(n)+1])
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#define IMM2_SIZE 1
+
+#define PUT2(a,n,d) \
+ a[n] = d
+
+#define GET2(a,n) \
+ a[n]
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
+
+/* When UTF encoding is being used, a character is no longer just a single
+character. The macros for character handling generate simple sequences when
+used in character-mode, and more complicated ones for UTF characters.
+GETCHARLENTEST and other macros are not used when UTF is not supported,
+so they are not defined. To make sure they can never even appear when
+UTF support is omitted, we don't even define them. */
+
+#ifndef SUPPORT_UTF
+
+/* #define MAX_VALUE_FOR_SINGLE_CHAR */
+/* #define HAS_EXTRALEN(c) */
+/* #define GET_EXTRALEN(c) */
+/* #define NOT_FIRSTCHAR(c) */
+#define GETCHAR(c, eptr) c = *eptr;
+#define GETCHARTEST(c, eptr) c = *eptr;
+#define GETCHARINC(c, eptr) c = *eptr++;
+#define GETCHARINCTEST(c, eptr) c = *eptr++;
+#define GETCHARLEN(c, eptr, len) c = *eptr;
+/* #define GETCHARLENTEST(c, eptr, len) */
+/* #define BACKCHAR(eptr) */
+/* #define FORWARDCHAR(eptr) */
+/* #define ACROSSCHAR(condition, eptr, action) */
+
+#else /* SUPPORT_UTF */
+
+#ifdef COMPILE_PCRE8
+
+/* These macros were originally written in the form of loops that used data
+from the tables whose names start with PRIV(utf8_table). They were rewritten by
+a user so as not to use loops, because in some environments this gives a
+significant performance advantage, and it seems never to do any harm. */
+
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 127
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) ((c) >= 0xc0)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer. */
+
+#define GETUTF8(c, eptr) \
+ { \
+ if ((c & 0x20) == 0) \
+ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
+ else if ((c & 0x10) == 0) \
+ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ else if ((c & 0x08) == 0) \
+ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
+ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
+ else if ((c & 0x04) == 0) \
+ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
+ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
+ (eptr[4] & 0x3f); \
+ else \
+ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
+ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
+ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
+ }
+
+/* Get the next UTF-8 character, not advancing the pointer. This is called when
+we know we are in UTF-8 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if (c >= 0xc0) GETUTF8(c, eptr);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && c >= 0xc0) GETUTF8(c, eptr);
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
+the pointer. */
+
+#define GETUTF8INC(c, eptr) \
+ { \
+ if ((c & 0x20) == 0) \
+ c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \
+ else if ((c & 0x10) == 0) \
+ { \
+ c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \
+ eptr += 2; \
+ } \
+ else if ((c & 0x08) == 0) \
+ { \
+ c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \
+ ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ eptr += 3; \
+ } \
+ else if ((c & 0x04) == 0) \
+ { \
+ c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \
+ ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \
+ (eptr[3] & 0x3f); \
+ eptr += 4; \
+ } \
+ else \
+ { \
+ c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \
+ ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \
+ ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \
+ eptr += 5; \
+ } \
+ }
+
+/* Get the next UTF-8 character, advancing the pointer. This is called when we
+know we are in UTF-8 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if (c >= 0xc0) GETUTF8INC(c, eptr);
+
+/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-8 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && c >= 0xc0) GETUTF8INC(c, eptr);
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF8LEN(c, eptr, len) \
+ { \
+ if ((c & 0x20) == 0) \
+ { \
+ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
+ len++; \
+ } \
+ else if ((c & 0x10) == 0) \
+ { \
+ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ len += 2; \
+ } \
+ else if ((c & 0x08) == 0) \
+ {\
+ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
+ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
+ len += 3; \
+ } \
+ else if ((c & 0x04) == 0) \
+ { \
+ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
+ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
+ (eptr[4] & 0x3f); \
+ len += 4; \
+ } \
+ else \
+ {\
+ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
+ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
+ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
+ len += 5; \
+ } \
+ }
+
+/* Get the next UTF-8 character, not advancing the pointer, incrementing length
+if there are extra bytes. This is called when we know we are in UTF-8 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if (c >= 0xc0) GETUTF8LEN(c, eptr, len);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
+pointer, incrementing length if there are extra bytes. This is called when we
+do not know if we are in UTF-8 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-8 mode - we don't put a test within the macro
+because almost all calls are already within a block of UTF-8 only code. */
+
+#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ while((condition) && ((eptr) & 0xc0) == 0x80) action
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 65535
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) 1
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer. */
+
+#define GETUTF16(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, not advancing the pointer. This is called when
+we know we are in UTF-16 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
+the pointer. */
+
+#define GETUTF16INC(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, advancing the pointer. This is called when we
+know we are in UTF-16 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-16 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF16LEN(c, eptr, len) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }
+
+/* Get the next UTF-16 character, not advancing the pointer, incrementing
+length if there is a low surrogate. This is called when we know we are in
+UTF-16 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
+pointer, incrementing length if there is a low surrogate. This is called when
+we do not know if we are in UTF-16 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-16 mode - we don't put a test within the
+macro because almost all calls are already within a block of UTF-16 only
+code. */
+
+#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action
+
+#endif
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+
+
+/* In case there is no definition of offsetof() provided - though any proper
+Standard C system should have one. */
+
+#ifndef offsetof
+#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
+#endif
+
+
+/* Private flags containing information about the compiled regex. They used to
+live at the top end of the options word, but that got almost full, so now they
+are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as
+the restrictions on partial matching have been lifted. It remains for backwards
+compatibility. */
+
+#ifdef COMPILE_PCRE8
+#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */
+#endif
+#ifdef COMPILE_PCRE16
+#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */
+#endif
+#define PCRE_FIRSTSET 0x0010 /* first_char is set */
+#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */
+#define PCRE_REQCHSET 0x0040 /* req_byte is set */
+#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */
+#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */
+#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */
+#define PCRE_JCHANGED 0x0400 /* j option used in regex */
+#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */
+#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */
+
+/* Flags for the "extra" block produced by pcre_study(). */
+
+#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */
+#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */
+
+/* Masks for identifying the public options that are permitted at compile
+time, run time, or study time, respectively. */
+
+#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
+ PCRE_NEWLINE_ANYCRLF)
+
+#define PUBLIC_COMPILE_OPTIONS \
+ (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
+ PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
+ PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
+ PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+ PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_EXEC_OPTIONS \
+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
+ PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_DFA_EXEC_OPTIONS \
+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
+ PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+ PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_STUDY_OPTIONS \
+ PCRE_STUDY_JIT_COMPILE
+
+/* Magic number to provide a small check against being handed junk. */
+
+#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
+
+/* This variable is used to detect a loaded regular expression
+in different endianness. */
+
+#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */
+
+/* Negative values for the firstchar and reqchar variables */
+
+#define REQ_UNSET (-2)
+#define REQ_NONE (-1)
+
+/* The maximum remaining length of subject we are prepared to search for a
+req_byte match. */
+
+#define REQ_BYTE_MAX 1000
+
+/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
+environments where these macros are defined elsewhere. Unfortunately, there
+is no way to do the same for the typedef. */
+
+typedef int BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
+character constants like '*' because the compiler would emit their EBCDIC code,
+which is different from their ASCII/UTF-8 code. Instead we define macros for
+the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
+is enabled. When UTF-8 support is not enabled, the definitions use character
+literals. Both character and string versions of each character are needed, and
+there are some longer strings as well.
+
+This means that, on EBCDIC platforms, the PCRE library can handle either
+EBCDIC, or UTF-8, but not both. To support both in the same compiled library
+would need different lookups depending on whether PCRE_UTF8 was set or not.
+This would make it impossible to use characters in switch/case statements,
+which would reduce performance. For a theoretical use (which nobody has asked
+for) in a minority area (EBCDIC platforms), this is not sensible. Any
+application that did need both could compile two versions of the library, using
+macros to give the functions distinct names. */
+
+#ifndef SUPPORT_UTF
+
+/* UTF-8 support is not enabled; use the platform-dependent character literals
+so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */
+
+#define CHAR_HT '\t'
+#define CHAR_VT '\v'
+#define CHAR_FF '\f'
+#define CHAR_CR '\r'
+#define CHAR_NL '\n'
+#define CHAR_BS '\b'
+#define CHAR_BEL '\a'
+#ifdef EBCDIC
+#define CHAR_ESC '\047'
+#define CHAR_DEL '\007'
+#else
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+#endif
+
+#define CHAR_SPACE ' '
+#define CHAR_EXCLAMATION_MARK '!'
+#define CHAR_QUOTATION_MARK '"'
+#define CHAR_NUMBER_SIGN '#'
+#define CHAR_DOLLAR_SIGN '$'
+#define CHAR_PERCENT_SIGN '%'
+#define CHAR_AMPERSAND '&'
+#define CHAR_APOSTROPHE '\''
+#define CHAR_LEFT_PARENTHESIS '('
+#define CHAR_RIGHT_PARENTHESIS ')'
+#define CHAR_ASTERISK '*'
+#define CHAR_PLUS '+'
+#define CHAR_COMMA ','
+#define CHAR_MINUS '-'
+#define CHAR_DOT '.'
+#define CHAR_SLASH '/'
+#define CHAR_0 '0'
+#define CHAR_1 '1'
+#define CHAR_2 '2'
+#define CHAR_3 '3'
+#define CHAR_4 '4'
+#define CHAR_5 '5'
+#define CHAR_6 '6'
+#define CHAR_7 '7'
+#define CHAR_8 '8'
+#define CHAR_9 '9'
+#define CHAR_COLON ':'
+#define CHAR_SEMICOLON ';'
+#define CHAR_LESS_THAN_SIGN '<'
+#define CHAR_EQUALS_SIGN '='
+#define CHAR_GREATER_THAN_SIGN '>'
+#define CHAR_QUESTION_MARK '?'
+#define CHAR_COMMERCIAL_AT '@'
+#define CHAR_A 'A'
+#define CHAR_B 'B'
+#define CHAR_C 'C'
+#define CHAR_D 'D'
+#define CHAR_E 'E'
+#define CHAR_F 'F'
+#define CHAR_G 'G'
+#define CHAR_H 'H'
+#define CHAR_I 'I'
+#define CHAR_J 'J'
+#define CHAR_K 'K'
+#define CHAR_L 'L'
+#define CHAR_M 'M'
+#define CHAR_N 'N'
+#define CHAR_O 'O'
+#define CHAR_P 'P'
+#define CHAR_Q 'Q'
+#define CHAR_R 'R'
+#define CHAR_S 'S'
+#define CHAR_T 'T'
+#define CHAR_U 'U'
+#define CHAR_V 'V'
+#define CHAR_W 'W'
+#define CHAR_X 'X'
+#define CHAR_Y 'Y'
+#define CHAR_Z 'Z'
+#define CHAR_LEFT_SQUARE_BRACKET '['
+#define CHAR_BACKSLASH '\\'
+#define CHAR_RIGHT_SQUARE_BRACKET ']'
+#define CHAR_CIRCUMFLEX_ACCENT '^'
+#define CHAR_UNDERSCORE '_'
+#define CHAR_GRAVE_ACCENT '`'
+#define CHAR_a 'a'
+#define CHAR_b 'b'
+#define CHAR_c 'c'
+#define CHAR_d 'd'
+#define CHAR_e 'e'
+#define CHAR_f 'f'
+#define CHAR_g 'g'
+#define CHAR_h 'h'
+#define CHAR_i 'i'
+#define CHAR_j 'j'
+#define CHAR_k 'k'
+#define CHAR_l 'l'
+#define CHAR_m 'm'
+#define CHAR_n 'n'
+#define CHAR_o 'o'
+#define CHAR_p 'p'
+#define CHAR_q 'q'
+#define CHAR_r 'r'
+#define CHAR_s 's'
+#define CHAR_t 't'
+#define CHAR_u 'u'
+#define CHAR_v 'v'
+#define CHAR_w 'w'
+#define CHAR_x 'x'
+#define CHAR_y 'y'
+#define CHAR_z 'z'
+#define CHAR_LEFT_CURLY_BRACKET '{'
+#define CHAR_VERTICAL_LINE '|'
+#define CHAR_RIGHT_CURLY_BRACKET '}'
+#define CHAR_TILDE '~'
+
+#define STR_HT "\t"
+#define STR_VT "\v"
+#define STR_FF "\f"
+#define STR_CR "\r"
+#define STR_NL "\n"
+#define STR_BS "\b"
+#define STR_BEL "\a"
+#ifdef EBCDIC
+#define STR_ESC "\047"
+#define STR_DEL "\007"
+#else
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+#endif
+
+#define STR_SPACE " "
+#define STR_EXCLAMATION_MARK "!"
+#define STR_QUOTATION_MARK "\""
+#define STR_NUMBER_SIGN "#"
+#define STR_DOLLAR_SIGN "$"
+#define STR_PERCENT_SIGN "%"
+#define STR_AMPERSAND "&"
+#define STR_APOSTROPHE "'"
+#define STR_LEFT_PARENTHESIS "("
+#define STR_RIGHT_PARENTHESIS ")"
+#define STR_ASTERISK "*"
+#define STR_PLUS "+"
+#define STR_COMMA ","
+#define STR_MINUS "-"
+#define STR_DOT "."
+#define STR_SLASH "/"
+#define STR_0 "0"
+#define STR_1 "1"
+#define STR_2 "2"
+#define STR_3 "3"
+#define STR_4 "4"
+#define STR_5 "5"
+#define STR_6 "6"
+#define STR_7 "7"
+#define STR_8 "8"
+#define STR_9 "9"
+#define STR_COLON ":"
+#define STR_SEMICOLON ";"
+#define STR_LESS_THAN_SIGN "<"
+#define STR_EQUALS_SIGN "="
+#define STR_GREATER_THAN_SIGN ">"
+#define STR_QUESTION_MARK "?"
+#define STR_COMMERCIAL_AT "@"
+#define STR_A "A"
+#define STR_B "B"
+#define STR_C "C"
+#define STR_D "D"
+#define STR_E "E"
+#define STR_F "F"
+#define STR_G "G"
+#define STR_H "H"
+#define STR_I "I"
+#define STR_J "J"
+#define STR_K "K"
+#define STR_L "L"
+#define STR_M "M"
+#define STR_N "N"
+#define STR_O "O"
+#define STR_P "P"
+#define STR_Q "Q"
+#define STR_R "R"
+#define STR_S "S"
+#define STR_T "T"
+#define STR_U "U"
+#define STR_V "V"
+#define STR_W "W"
+#define STR_X "X"
+#define STR_Y "Y"
+#define STR_Z "Z"
+#define STR_LEFT_SQUARE_BRACKET "["
+#define STR_BACKSLASH "\\"
+#define STR_RIGHT_SQUARE_BRACKET "]"
+#define STR_CIRCUMFLEX_ACCENT "^"
+#define STR_UNDERSCORE "_"
+#define STR_GRAVE_ACCENT "`"
+#define STR_a "a"
+#define STR_b "b"
+#define STR_c "c"
+#define STR_d "d"
+#define STR_e "e"
+#define STR_f "f"
+#define STR_g "g"
+#define STR_h "h"
+#define STR_i "i"
+#define STR_j "j"
+#define STR_k "k"
+#define STR_l "l"
+#define STR_m "m"
+#define STR_n "n"
+#define STR_o "o"
+#define STR_p "p"
+#define STR_q "q"
+#define STR_r "r"
+#define STR_s "s"
+#define STR_t "t"
+#define STR_u "u"
+#define STR_v "v"
+#define STR_w "w"
+#define STR_x "x"
+#define STR_y "y"
+#define STR_z "z"
+#define STR_LEFT_CURLY_BRACKET "{"
+#define STR_VERTICAL_LINE "|"
+#define STR_RIGHT_CURLY_BRACKET "}"
+#define STR_TILDE "~"
+
+#define STRING_ACCEPT0 "ACCEPT\0"
+#define STRING_COMMIT0 "COMMIT\0"
+#define STRING_F0 "F\0"
+#define STRING_FAIL0 "FAIL\0"
+#define STRING_MARK0 "MARK\0"
+#define STRING_PRUNE0 "PRUNE\0"
+#define STRING_SKIP0 "SKIP\0"
+#define STRING_THEN "THEN"
+
+#define STRING_alpha0 "alpha\0"
+#define STRING_lower0 "lower\0"
+#define STRING_upper0 "upper\0"
+#define STRING_alnum0 "alnum\0"
+#define STRING_ascii0 "ascii\0"
+#define STRING_blank0 "blank\0"
+#define STRING_cntrl0 "cntrl\0"
+#define STRING_digit0 "digit\0"
+#define STRING_graph0 "graph\0"
+#define STRING_print0 "print\0"
+#define STRING_punct0 "punct\0"
+#define STRING_space0 "space\0"
+#define STRING_word0 "word\0"
+#define STRING_xdigit "xdigit"
+
+#define STRING_DEFINE "DEFINE"
+
+#define STRING_CR_RIGHTPAR "CR)"
+#define STRING_LF_RIGHTPAR "LF)"
+#define STRING_CRLF_RIGHTPAR "CRLF)"
+#define STRING_ANY_RIGHTPAR "ANY)"
+#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
+#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
+#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR "UTF8)"
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR "UTF16)"
+#endif
+#define STRING_UCP_RIGHTPAR "UCP)"
+#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+
+#else /* SUPPORT_UTF */
+
+/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
+works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
+only. */
+
+#define CHAR_HT '\011'
+#define CHAR_VT '\013'
+#define CHAR_FF '\014'
+#define CHAR_CR '\015'
+#define CHAR_NL '\012'
+#define CHAR_BS '\010'
+#define CHAR_BEL '\007'
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+
+#define CHAR_SPACE '\040'
+#define CHAR_EXCLAMATION_MARK '\041'
+#define CHAR_QUOTATION_MARK '\042'
+#define CHAR_NUMBER_SIGN '\043'
+#define CHAR_DOLLAR_SIGN '\044'
+#define CHAR_PERCENT_SIGN '\045'
+#define CHAR_AMPERSAND '\046'
+#define CHAR_APOSTROPHE '\047'
+#define CHAR_LEFT_PARENTHESIS '\050'
+#define CHAR_RIGHT_PARENTHESIS '\051'
+#define CHAR_ASTERISK '\052'
+#define CHAR_PLUS '\053'
+#define CHAR_COMMA '\054'
+#define CHAR_MINUS '\055'
+#define CHAR_DOT '\056'
+#define CHAR_SLASH '\057'
+#define CHAR_0 '\060'
+#define CHAR_1 '\061'
+#define CHAR_2 '\062'
+#define CHAR_3 '\063'
+#define CHAR_4 '\064'
+#define CHAR_5 '\065'
+#define CHAR_6 '\066'
+#define CHAR_7 '\067'
+#define CHAR_8 '\070'
+#define CHAR_9 '\071'
+#define CHAR_COLON '\072'
+#define CHAR_SEMICOLON '\073'
+#define CHAR_LESS_THAN_SIGN '\074'
+#define CHAR_EQUALS_SIGN '\075'
+#define CHAR_GREATER_THAN_SIGN '\076'
+#define CHAR_QUESTION_MARK '\077'
+#define CHAR_COMMERCIAL_AT '\100'
+#define CHAR_A '\101'
+#define CHAR_B '\102'
+#define CHAR_C '\103'
+#define CHAR_D '\104'
+#define CHAR_E '\105'
+#define CHAR_F '\106'
+#define CHAR_G '\107'
+#define CHAR_H '\110'
+#define CHAR_I '\111'
+#define CHAR_J '\112'
+#define CHAR_K '\113'
+#define CHAR_L '\114'
+#define CHAR_M '\115'
+#define CHAR_N '\116'
+#define CHAR_O '\117'
+#define CHAR_P '\120'
+#define CHAR_Q '\121'
+#define CHAR_R '\122'
+#define CHAR_S '\123'
+#define CHAR_T '\124'
+#define CHAR_U '\125'
+#define CHAR_V '\126'
+#define CHAR_W '\127'
+#define CHAR_X '\130'
+#define CHAR_Y '\131'
+#define CHAR_Z '\132'
+#define CHAR_LEFT_SQUARE_BRACKET '\133'
+#define CHAR_BACKSLASH '\134'
+#define CHAR_RIGHT_SQUARE_BRACKET '\135'
+#define CHAR_CIRCUMFLEX_ACCENT '\136'
+#define CHAR_UNDERSCORE '\137'
+#define CHAR_GRAVE_ACCENT '\140'
+#define CHAR_a '\141'
+#define CHAR_b '\142'
+#define CHAR_c '\143'
+#define CHAR_d '\144'
+#define CHAR_e '\145'
+#define CHAR_f '\146'
+#define CHAR_g '\147'
+#define CHAR_h '\150'
+#define CHAR_i '\151'
+#define CHAR_j '\152'
+#define CHAR_k '\153'
+#define CHAR_l '\154'
+#define CHAR_m '\155'
+#define CHAR_n '\156'
+#define CHAR_o '\157'
+#define CHAR_p '\160'
+#define CHAR_q '\161'
+#define CHAR_r '\162'
+#define CHAR_s '\163'
+#define CHAR_t '\164'
+#define CHAR_u '\165'
+#define CHAR_v '\166'
+#define CHAR_w '\167'
+#define CHAR_x '\170'
+#define CHAR_y '\171'
+#define CHAR_z '\172'
+#define CHAR_LEFT_CURLY_BRACKET '\173'
+#define CHAR_VERTICAL_LINE '\174'
+#define CHAR_RIGHT_CURLY_BRACKET '\175'
+#define CHAR_TILDE '\176'
+
+#define STR_HT "\011"
+#define STR_VT "\013"
+#define STR_FF "\014"
+#define STR_CR "\015"
+#define STR_NL "\012"
+#define STR_BS "\010"
+#define STR_BEL "\007"
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+
+#define STR_SPACE "\040"
+#define STR_EXCLAMATION_MARK "\041"
+#define STR_QUOTATION_MARK "\042"
+#define STR_NUMBER_SIGN "\043"
+#define STR_DOLLAR_SIGN "\044"
+#define STR_PERCENT_SIGN "\045"
+#define STR_AMPERSAND "\046"
+#define STR_APOSTROPHE "\047"
+#define STR_LEFT_PARENTHESIS "\050"
+#define STR_RIGHT_PARENTHESIS "\051"
+#define STR_ASTERISK "\052"
+#define STR_PLUS "\053"
+#define STR_COMMA "\054"
+#define STR_MINUS "\055"
+#define STR_DOT "\056"
+#define STR_SLASH "\057"
+#define STR_0 "\060"
+#define STR_1 "\061"
+#define STR_2 "\062"
+#define STR_3 "\063"
+#define STR_4 "\064"
+#define STR_5 "\065"
+#define STR_6 "\066"
+#define STR_7 "\067"
+#define STR_8 "\070"
+#define STR_9 "\071"
+#define STR_COLON "\072"
+#define STR_SEMICOLON "\073"
+#define STR_LESS_THAN_SIGN "\074"
+#define STR_EQUALS_SIGN "\075"
+#define STR_GREATER_THAN_SIGN "\076"
+#define STR_QUESTION_MARK "\077"
+#define STR_COMMERCIAL_AT "\100"
+#define STR_A "\101"
+#define STR_B "\102"
+#define STR_C "\103"
+#define STR_D "\104"
+#define STR_E "\105"
+#define STR_F "\106"
+#define STR_G "\107"
+#define STR_H "\110"
+#define STR_I "\111"
+#define STR_J "\112"
+#define STR_K "\113"
+#define STR_L "\114"
+#define STR_M "\115"
+#define STR_N "\116"
+#define STR_O "\117"
+#define STR_P "\120"
+#define STR_Q "\121"
+#define STR_R "\122"
+#define STR_S "\123"
+#define STR_T "\124"
+#define STR_U "\125"
+#define STR_V "\126"
+#define STR_W "\127"
+#define STR_X "\130"
+#define STR_Y "\131"
+#define STR_Z "\132"
+#define STR_LEFT_SQUARE_BRACKET "\133"
+#define STR_BACKSLASH "\134"
+#define STR_RIGHT_SQUARE_BRACKET "\135"
+#define STR_CIRCUMFLEX_ACCENT "\136"
+#define STR_UNDERSCORE "\137"
+#define STR_GRAVE_ACCENT "\140"
+#define STR_a "\141"
+#define STR_b "\142"
+#define STR_c "\143"
+#define STR_d "\144"
+#define STR_e "\145"
+#define STR_f "\146"
+#define STR_g "\147"
+#define STR_h "\150"
+#define STR_i "\151"
+#define STR_j "\152"
+#define STR_k "\153"
+#define STR_l "\154"
+#define STR_m "\155"
+#define STR_n "\156"
+#define STR_o "\157"
+#define STR_p "\160"
+#define STR_q "\161"
+#define STR_r "\162"
+#define STR_s "\163"
+#define STR_t "\164"
+#define STR_u "\165"
+#define STR_v "\166"
+#define STR_w "\167"
+#define STR_x "\170"
+#define STR_y "\171"
+#define STR_z "\172"
+#define STR_LEFT_CURLY_BRACKET "\173"
+#define STR_VERTICAL_LINE "\174"
+#define STR_RIGHT_CURLY_BRACKET "\175"
+#define STR_TILDE "\176"
+
+#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
+#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
+#define STRING_F0 STR_F "\0"
+#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
+#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
+#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
+#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
+#define STRING_THEN STR_T STR_H STR_E STR_N
+
+#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
+#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
+#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
+#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
+#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
+#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
+#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
+#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
+#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
+#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
+#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
+#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
+#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
+#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
+
+#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
+
+#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
+#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
+#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#endif
+#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
+#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
+
+#endif /* SUPPORT_UTF */
+
+/* Escape items that are just an encoding of a particular data value. */
+
+#ifndef ESC_e
+#define ESC_e CHAR_ESC
+#endif
+
+#ifndef ESC_f
+#define ESC_f CHAR_FF
+#endif
+
+#ifndef ESC_n
+#define ESC_n CHAR_NL
+#endif
+
+#ifndef ESC_r
+#define ESC_r CHAR_CR
+#endif
+
+/* We can't officially use ESC_t because it is a POSIX reserved identifier
+(presumably because of all the others like size_t). */
+
+#ifndef ESC_tee
+#define ESC_tee CHAR_HT
+#endif
+
+/* Codes for different types of Unicode property */
+
+#define PT_ANY 0 /* Any property - matches all chars */
+#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
+#define PT_GC 2 /* Specified general characteristic (e.g. L) */
+#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
+#define PT_SC 4 /* Script (e.g. Han) */
+#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */
+#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */
+#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
+#define PT_WORD 8 /* Word - L plus N plus underscore */
+
+/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
+contain characters with values greater than 255. */
+
+#define XCL_NOT 0x01 /* Flag: this is a negative class */
+#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
+
+#define XCL_END 0 /* Marks end of individual items */
+#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
+#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
+#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
+#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
+
+/* These are escaped items that aren't just an encoding of a particular data
+value such as \n. They must have non-zero values, as check_escape() returns
+their negation. Also, they must appear in the same order as in the opcode
+definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
+corresponds to "." in DOTALL mode rather than an escape sequence. It is also
+used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
+non-DOTALL mode, "." behaves like \N.
+
+The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
+when PCRE_UCP is set, when replacement of \d etc by \p sequences is required.
+They must be contiguous, and remain in order so that the replacements can be
+looked up from a table.
+
+The final escape must be ESC_REF as subsequent values are used for
+backreferences (\1, \2, \3, etc). There are two tests in the code for an escape
+greater than ESC_b and less than ESC_Z to detect the types that may be
+repeated. These are the types that consume characters. If any new escapes are
+put in between that don't consume a character, that code will have to change.
+*/
+
+enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
+ ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
+ ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
+ ESC_E, ESC_Q, ESC_g, ESC_k,
+ ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu,
+ ESC_REF };
+
+/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
+OP_EOD must correspond in order to the list of escapes immediately above.
+
+*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
+that follow must also be updated to match. There are also tables called
+"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+
+enum {
+ OP_END, /* 0 End of pattern */
+
+ /* Values corresponding to backslashed metacharacters */
+
+ OP_SOD, /* 1 Start of data: \A */
+ OP_SOM, /* 2 Start of match (subject + offset): \G */
+ OP_SET_SOM, /* 3 Set start of match (\K) */
+ OP_NOT_WORD_BOUNDARY, /* 4 \B */
+ OP_WORD_BOUNDARY, /* 5 \b */
+ OP_NOT_DIGIT, /* 6 \D */
+ OP_DIGIT, /* 7 \d */
+ OP_NOT_WHITESPACE, /* 8 \S */
+ OP_WHITESPACE, /* 9 \s */
+ OP_NOT_WORDCHAR, /* 10 \W */
+ OP_WORDCHAR, /* 11 \w */
+
+ OP_ANY, /* 12 Match any character except newline */
+ OP_ALLANY, /* 13 Match any character */
+ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
+ OP_NOTPROP, /* 15 \P (not Unicode property) */
+ OP_PROP, /* 16 \p (Unicode property) */
+ OP_ANYNL, /* 17 \R (any newline sequence) */
+ OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
+ OP_HSPACE, /* 19 \h (horizontal whitespace) */
+ OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
+ OP_VSPACE, /* 21 \v (vertical whitespace) */
+ OP_EXTUNI, /* 22 \X (extended Unicode sequence */
+ OP_EODN, /* 23 End of data or \n at end of data: \Z. */
+ OP_EOD, /* 24 End of data: \z */
+
+ OP_CIRC, /* 25 Start of line - not multiline */
+ OP_CIRCM, /* 26 Start of line - multiline */
+ OP_DOLL, /* 27 End of line - not multiline */
+ OP_DOLLM, /* 28 End of line - multiline */
+ OP_CHAR, /* 29 Match one character, casefully */
+ OP_CHARI, /* 30 Match one character, caselessly */
+ OP_NOT, /* 31 Match one character, not the given one, casefully */
+ OP_NOTI, /* 32 Match one character, not the given one, caselessly */
+
+ /* The following sets of 13 opcodes must always be kept in step because
+ the offset from the first one is used to generate the others. */
+
+ /**** Single characters, caseful, must precede the caseless ones ****/
+
+ OP_STAR, /* 33 The maximizing and minimizing versions of */
+ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
+ OP_PLUS, /* 35 the minimizing one second. */
+ OP_MINPLUS, /* 36 */
+ OP_QUERY, /* 37 */
+ OP_MINQUERY, /* 38 */
+
+ OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
+ OP_MINUPTO, /* 40 */
+ OP_EXACT, /* 41 Exactly n matches */
+
+ OP_POSSTAR, /* 42 Possessified star, caseful */
+ OP_POSPLUS, /* 43 Possessified plus, caseful */
+ OP_POSQUERY, /* 44 Posesssified query, caseful */
+ OP_POSUPTO, /* 45 Possessified upto, caseful */
+
+ /**** Single characters, caseless, must follow the caseful ones */
+
+ OP_STARI, /* 46 */
+ OP_MINSTARI, /* 47 */
+ OP_PLUSI, /* 48 */
+ OP_MINPLUSI, /* 49 */
+ OP_QUERYI, /* 50 */
+ OP_MINQUERYI, /* 51 */
+
+ OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
+ OP_MINUPTOI, /* 53 */
+ OP_EXACTI, /* 54 */
+
+ OP_POSSTARI, /* 55 Possessified star, caseless */
+ OP_POSPLUSI, /* 56 Possessified plus, caseless */
+ OP_POSQUERYI, /* 57 Posesssified query, caseless */
+ OP_POSUPTOI, /* 58 Possessified upto, caseless */
+
+ /**** The negated ones must follow the non-negated ones, and match them ****/
+ /**** Negated single character, caseful; must precede the caseless ones ****/
+
+ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
+ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
+ OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
+ OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
+ OP_NOTQUERY, /* 63 */
+ OP_NOTMINQUERY, /* 64 */
+
+ OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
+ OP_NOTMINUPTO, /* 66 */
+ OP_NOTEXACT, /* 67 Exactly n matches */
+
+ OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
+ OP_NOTPOSPLUS, /* 69 */
+ OP_NOTPOSQUERY, /* 70 */
+ OP_NOTPOSUPTO, /* 71 */
+
+ /**** Negated single character, caseless; must follow the caseful ones ****/
+
+ OP_NOTSTARI, /* 72 */
+ OP_NOTMINSTARI, /* 73 */
+ OP_NOTPLUSI, /* 74 */
+ OP_NOTMINPLUSI, /* 75 */
+ OP_NOTQUERYI, /* 76 */
+ OP_NOTMINQUERYI, /* 77 */
+
+ OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
+ OP_NOTMINUPTOI, /* 79 */
+ OP_NOTEXACTI, /* 80 Exactly n matches */
+
+ OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
+ OP_NOTPOSPLUSI, /* 82 */
+ OP_NOTPOSQUERYI, /* 83 */
+ OP_NOTPOSUPTOI, /* 84 */
+
+ /**** Character types ****/
+
+ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
+ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
+ OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
+ OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
+ OP_TYPEQUERY, /* 89 */
+ OP_TYPEMINQUERY, /* 90 */
+
+ OP_TYPEUPTO, /* 91 From 0 to n matches */
+ OP_TYPEMINUPTO, /* 92 */
+ OP_TYPEEXACT, /* 93 Exactly n matches */
+
+ OP_TYPEPOSSTAR, /* 94 Possessified versions */
+ OP_TYPEPOSPLUS, /* 95 */
+ OP_TYPEPOSQUERY, /* 96 */
+ OP_TYPEPOSUPTO, /* 97 */
+
+ /* These are used for character classes and back references; only the
+ first six are the same as the sets above. */
+
+ OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
+ OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
+ OP_CRPLUS, /* 100 the minimizing one second. These codes must */
+ OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
+ OP_CRQUERY, /* 102 */
+ OP_CRMINQUERY, /* 103 */
+
+ OP_CRRANGE, /* 104 These are different to the three sets above. */
+ OP_CRMINRANGE, /* 105 */
+
+ /* End of quantifier opcodes */
+
+ OP_CLASS, /* 106 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 107 Same, but the bitmap was created from a negative
+ class - the difference is relevant only when a
+ character > 255 is encountered. */
+ OP_XCLASS, /* 108 Extended class for handling > 255 chars within the
+ class. This does both positive and negative. */
+ OP_REF, /* 109 Match a back reference, casefully */
+ OP_REFI, /* 110 Match a back reference, caselessly */
+ OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 112 Call out to external function if provided */
+
+ OP_ALT, /* 113 Start of alternation */
+ OP_KET, /* 114 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 115 These two must remain together and in this */
+ OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 117 Possessive unlimited repeat. */
+
+ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
+ asserts must remain in order. */
+
+ OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 119 Positive lookahead */
+ OP_ASSERT_NOT, /* 120 Negative lookahead */
+ OP_ASSERTBACK, /* 121 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */
+
+ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
+ after the assertions, with ONCE first, as there's a test for >= ONCE for a
+ subpattern that isn't an assertion. The POS versions must immediately follow
+ the non-POS versions in each case. */
+
+ OP_ONCE, /* 123 Atomic group, contains captures */
+ OP_ONCE_NC, /* 124 Atomic group containing no captures */
+ OP_BRA, /* 125 Start of non-capturing bracket */
+ OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 127 Start of capturing bracket */
+ OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 129 Conditional group */
+
+ /* These five must follow the previous five, in the same order. There's a
+ check for >= SBRA to distinguish the two sets. */
+
+ OP_SBRA, /* 130 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 132 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 134 Conditional group, check empty */
+
+ /* The next two pairs must (respectively) be kept together. */
+
+ OP_CREF, /* 135 Used to hold a capture number as condition */
+ OP_NCREF, /* 136 Same, but generated by a name reference*/
+ OP_RREF, /* 137 Used to hold a recursion number as condition */
+ OP_NRREF, /* 138 Same, but generated by a name reference*/
+ OP_DEF, /* 139 The DEFINE condition */
+
+ OP_BRAZERO, /* 140 These two must remain together and in this */
+ OP_BRAMINZERO, /* 141 order. */
+ OP_BRAPOSZERO, /* 142 */
+
+ /* These are backtracking control verbs */
+
+ OP_MARK, /* 143 always has an argument */
+ OP_PRUNE, /* 144 */
+ OP_PRUNE_ARG, /* 145 same, but with argument */
+ OP_SKIP, /* 146 */
+ OP_SKIP_ARG, /* 147 same, but with argument */
+ OP_THEN, /* 148 */
+ OP_THEN_ARG, /* 149 same, but with argument */
+ OP_COMMIT, /* 150 */
+
+ /* These are forced failure and success verbs */
+
+ OP_FAIL, /* 151 */
+ OP_ACCEPT, /* 152 */
+ OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
+ OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
+
+ /* This is used to skip a subpattern with a {0} quantifier */
+
+ OP_SKIPZERO, /* 155 */
+
+ /* This is not an opcode, but is used to check that tables indexed by opcode
+ are the correct length, in order to catch updating errors - there have been
+ some in the past. */
+
+ OP_TABLE_LENGTH
+};
+
+/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
+definitions that follow must also be updated to match. There are also tables
+called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+
+
+/* This macro defines textual names for all the opcodes. These are used only
+for debugging, and some of them are only partial names. The macro is referenced
+only in pcre_printint.c, which fills out the full names in many cases (and in
+some cases doesn't actually use these names at all). */
+
+#define OP_NAME_LIST \
+ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
+ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
+ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
+ "extuni", "\\Z", "\\z", \
+ "^", "^", "$", "$", "char", "chari", "not", "noti", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", \
+ "class", "nclass", "xclass", "Ref", "Refi", \
+ "Recurse", "Callout", \
+ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
+ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
+ "Once", "Once_NC", \
+ "Bra", "BraPos", "CBra", "CBraPos", \
+ "Cond", \
+ "SBra", "SBraPos", "SCBra", "SCBraPos", \
+ "SCond", \
+ "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
+ "Brazero", "Braminzero", "Braposzero", \
+ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
+ "*THEN", "*THEN", "*COMMIT", "*FAIL", \
+ "*ACCEPT", "*ASSERT_ACCEPT", \
+ "Close", "Skip zero"
+
+
+/* This macro defines the length of fixed length operations in the compiled
+regex. The lengths are used when searching for specific things, and also in the
+debugging printing of a compiled regex. We use a macro so that it can be
+defined close to the definitions of the opcodes themselves.
+
+As things have been extended, some of these are no longer fixed lenths, but are
+minima instead. For example, the length of a single-character repeat may vary
+in UTF-8 mode. The code that uses this table must know about such things. */
+
+#define OP_LENGTHS \
+ 1, /* End */ \
+ 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
+ 1, 1, 1, /* Any, AllAny, Anybyte */ \
+ 3, 3, /* \P, \p */ \
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
+ 1, /* \X */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
+ 2, /* Char - the minimum length */ \
+ 2, /* Chari - the minimum length */ \
+ 2, /* not */ \
+ 2, /* noti */ \
+ /* Positive single-char repeats ** These are */ \
+ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
+ 2+IMM2_SIZE, /* exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
+ 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
+ 2+IMM2_SIZE, /* exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
+ /* Negative single-char repeats - only for chars < 256 */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
+ 2+IMM2_SIZE, /* NOT exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
+ 2+IMM2_SIZE, /* NOT exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
+ /* Positive type repeats */ \
+ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
+ 2+IMM2_SIZE, /* Type exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
+ /* Character class & ref repeats */ \
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
+ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1+(32/sizeof(pcre_uchar)), /* CLASS */ \
+ 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
+ 0, /* XCLASS - variable length */ \
+ 1+IMM2_SIZE, /* REF */ \
+ 1+IMM2_SIZE, /* REFI */ \
+ 1+LINK_SIZE, /* RECURSE */ \
+ 2+2*LINK_SIZE, /* CALLOUT */ \
+ 1+LINK_SIZE, /* Alt */ \
+ 1+LINK_SIZE, /* Ket */ \
+ 1+LINK_SIZE, /* KetRmax */ \
+ 1+LINK_SIZE, /* KetRmin */ \
+ 1+LINK_SIZE, /* KetRpos */ \
+ 1+LINK_SIZE, /* Reverse */ \
+ 1+LINK_SIZE, /* Assert */ \
+ 1+LINK_SIZE, /* Assert not */ \
+ 1+LINK_SIZE, /* Assert behind */ \
+ 1+LINK_SIZE, /* Assert behind not */ \
+ 1+LINK_SIZE, /* ONCE */ \
+ 1+LINK_SIZE, /* ONCE_NC */ \
+ 1+LINK_SIZE, /* BRA */ \
+ 1+LINK_SIZE, /* BRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
+ 1+LINK_SIZE, /* COND */ \
+ 1+LINK_SIZE, /* SBRA */ \
+ 1+LINK_SIZE, /* SBRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
+ 1+LINK_SIZE, /* SCOND */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
+ 1, /* DEF */ \
+ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
+ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
+ 1, 3, /* SKIP, SKIP_ARG */ \
+ 1, 3, /* THEN, THEN_ARG */ \
+ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
+ 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */
+
+/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
+condition. */
+
+#define RREF_ANY 0xffff
+
+/* Compile time error code numbers. They are given names so that they can more
+easily be tracked. When a new number is added, the table called eint in
+pcreposix.c must be updated. */
+
+enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
+ ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
+ ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
+ ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
+ ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
+ ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
+ ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
+ ERR70, ERR71, ERR72, ERR73, ERR74, ERRCOUNT };
+
+/* The real format of the start of the pcre block; the index of names and the
+code vector run on as long as necessary after the end. We store an explicit
+offset to the name table so that if a regex is compiled on one host, saved, and
+then run on another where the size of pointers is different, all might still
+be well. For the case of compiled-on-4 and run-on-8, we include an extra
+pointer that is always NULL. For future-proofing, a few dummy fields were
+originally included - even though you can never get this planning right - but
+there is only one left now.
+
+NOTE NOTE NOTE:
+Because people can now save and re-use compiled patterns, any additions to this
+structure should be made at the end, and something earlier (e.g. a new
+flag in the options or one of the dummy fields) should indicate that the new
+fields are present. Currently PCRE always sets the dummy fields to zero.
+NOTE NOTE NOTE
+*/
+
+#ifdef COMPILE_PCRE8
+#define REAL_PCRE real_pcre
+#else
+#define REAL_PCRE real_pcre16
+#endif
+
+typedef struct REAL_PCRE {
+ pcre_uint32 magic_number;
+ pcre_uint32 size; /* Total that was malloced */
+ pcre_uint32 options; /* Public options */
+ pcre_uint16 flags; /* Private flags */
+ pcre_uint16 dummy1; /* For future use */
+ pcre_uint16 top_bracket;
+ pcre_uint16 top_backref;
+ pcre_uint16 first_char; /* Starting character */
+ pcre_uint16 req_char; /* This character must be seen */
+ pcre_uint16 name_table_offset; /* Offset to name table that follows */
+ pcre_uint16 name_entry_size; /* Size of any name items */
+ pcre_uint16 name_count; /* Number of name items */
+ pcre_uint16 ref_count; /* Reference count */
+
+ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
+ const pcre_uint8 *nullpad; /* NULL padding */
+} REAL_PCRE;
+
+/* The format of the block used to store data from pcre_study(). The same
+remark (see NOTE above) about extending this structure applies. */
+
+typedef struct pcre_study_data {
+ pcre_uint32 size; /* Total that was malloced */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint8 start_bits[32]; /* Starting char bits */
+ pcre_uint32 minlength; /* Minimum subject length */
+} pcre_study_data;
+
+/* Structure for building a chain of open capturing subpatterns during
+compiling, so that instructions to close them can be compiled when (*ACCEPT) is
+encountered. This is also used to identify subpatterns that contain recursive
+back references to themselves, so that they can be made atomic. */
+
+typedef struct open_capitem {
+ struct open_capitem *next; /* Chain link */
+ pcre_uint16 number; /* Capture number */
+ pcre_uint16 flag; /* Set TRUE if recursive back ref */
+} open_capitem;
+
+/* Structure for passing "static" information around between the functions
+doing the compiling, so that they are thread-safe. */
+
+typedef struct compile_data {
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *cbits; /* Points to character type table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ const pcre_uchar *start_workspace;/* The start of working space */
+ const pcre_uchar *start_code; /* The start of the compiled code */
+ const pcre_uchar *start_pattern; /* The start of the pattern */
+ const pcre_uchar *end_pattern; /* The end of the pattern */
+ open_capitem *open_caps; /* Chain of open capture items */
+ pcre_uchar *hwm; /* High watermark of workspace */
+ pcre_uchar *name_table; /* The name/number table */
+ int names_found; /* Number of entries so far */
+ int name_entry_size; /* Size of each entry */
+ int workspace_size; /* Size of workspace */
+ int bracount; /* Count of capturing parens as we compile */
+ int final_bracount; /* Saved value after first pass */
+ int top_backref; /* Maximum back reference */
+ unsigned int backref_map; /* Bitmap of low back refs */
+ int assert_depth; /* Depth of nested assertions */
+ int external_options; /* External (initial) options */
+ int external_flags; /* External flag bits to be set */
+ int req_varyopt; /* "After variable item" flag for reqbyte */
+ BOOL had_accept; /* (*ACCEPT) encountered */
+ BOOL check_lookbehind; /* Lookbehinds need later checking */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed length */
+} compile_data;
+
+/* Structure for maintaining a chain of pointers to the currently incomplete
+branches, for testing for left recursion while compiling. */
+
+typedef struct branch_chain {
+ struct branch_chain *outer;
+ pcre_uchar *current_branch;
+} branch_chain;
+
+/* Structure for items in a linked list that represents an explicit recursive
+call within the pattern; used by pcre_exec(). */
+
+typedef struct recursion_info {
+ struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
+ int group_num; /* Number of group that was called */
+ int *offset_save; /* Pointer to start of saved offsets */
+ int saved_max; /* Number of saved offsets */
+ PCRE_PUCHAR subject_position; /* Position at start of recursion */
+} recursion_info;
+
+/* A similar structure for pcre_dfa_exec(). */
+
+typedef struct dfa_recursion_info {
+ struct dfa_recursion_info *prevrec;
+ int group_num;
+ PCRE_PUCHAR subject_position;
+} dfa_recursion_info;
+
+/* Structure for building a chain of data for holding the values of the subject
+pointer at the start of each subpattern, so as to detect when an empty string
+has been matched by a subpattern - to break infinite loops; used by
+pcre_exec(). */
+
+typedef struct eptrblock {
+ struct eptrblock *epb_prev;
+ PCRE_PUCHAR epb_saved_eptr;
+} eptrblock;
+
+
+/* Structure for passing "static" information around between the functions
+doing traditional NFA matching, so that they are thread-safe. */
+
+typedef struct match_data {
+ unsigned long int match_call_count; /* As it says */
+ unsigned long int match_limit; /* As it says */
+ unsigned long int match_limit_recursion; /* As it says */
+ int *offset_vector; /* Offset vector */
+ int offset_end; /* One past the end */
+ int offset_max; /* The maximum usable for return data */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ int name_count; /* Number of names in name table */
+ int name_entry_size; /* Size of entry in names table */
+ pcre_uchar *name_table; /* Table of names */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ BOOL offset_overflow; /* Set if too many extractions */
+ BOOL notbol; /* NOTBOL flag */
+ BOOL noteol; /* NOTEOL flag */
+ BOOL utf; /* UTF-8 / UTF-16 flag */
+ BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
+ BOOL use_ucp; /* PCRE_UCP flag */
+ BOOL endonly; /* Dollar not before final \n */
+ BOOL notempty; /* Empty string match not wanted */
+ BOOL notempty_atstart; /* Empty string match at start not wanted */
+ BOOL hitend; /* Hit the end of the subject at some point */
+ BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
+ BOOL hasthen; /* Pattern contains (*THEN) */
+ BOOL ignore_skip_arg; /* For re-run when SKIP name not found */
+ const pcre_uchar *start_code; /* For use when recursing */
+ PCRE_PUCHAR start_subject; /* Start of the subject string */
+ PCRE_PUCHAR end_subject; /* End of the subject string */
+ PCRE_PUCHAR start_match_ptr; /* Start of matched string */
+ PCRE_PUCHAR end_match_ptr; /* Subject position at end match */
+ PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */
+ int partial; /* PARTIAL options */
+ int end_offset_top; /* Highwater mark at end of match */
+ int capture_last; /* Most recent capture number */
+ int start_offset; /* The start offset value */
+ int match_function_type; /* Set for certain special calls of MATCH() */
+ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
+ int eptrn; /* Next free eptrblock */
+ recursion_info *recursive; /* Linked list of recursion data */
+ void *callout_data; /* To pass back to callouts */
+ const pcre_uchar *mark; /* Mark pointer to pass back on success */
+ const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
+ const pcre_uchar *once_target; /* Where to back up to for atomic groups */
+} match_data;
+
+/* A similar structure is used for the same purpose by the DFA matching
+functions. */
+
+typedef struct dfa_match_data {
+ const pcre_uchar *start_code; /* Start of the compiled pattern */
+ const pcre_uchar *start_subject ; /* Start of the subject string */
+ const pcre_uchar *end_subject; /* End of subject string */
+ const pcre_uchar *start_used_ptr; /* Earliest consulted character */
+ const pcre_uint8 *tables; /* Character tables */
+ int start_offset; /* The start offset value */
+ int moptions; /* Match options */
+ int poptions; /* Pattern options */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ void *callout_data; /* To pass back to callouts */
+ dfa_recursion_info *recursive; /* Linked list of recursion data */
+} dfa_match_data;
+
+/* Bit definitions for entries in the pcre_ctypes table. */
+
+#define ctype_space 0x01
+#define ctype_letter 0x02
+#define ctype_digit 0x04
+#define ctype_xdigit 0x08
+#define ctype_word 0x10 /* alphanumeric or '_' */
+#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
+
+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
+of bits for a class map. Some classes are built by combining these tables. */
+
+#define cbit_space 0 /* [:space:] or \s */
+#define cbit_xdigit 32 /* [:xdigit:] */
+#define cbit_digit 64 /* [:digit:] or \d */
+#define cbit_upper 96 /* [:upper:] */
+#define cbit_lower 128 /* [:lower:] */
+#define cbit_word 160 /* [:word:] or \w */
+#define cbit_graph 192 /* [:graph:] */
+#define cbit_print 224 /* [:print:] */
+#define cbit_punct 256 /* [:punct:] */
+#define cbit_cntrl 288 /* [:cntrl:] */
+#define cbit_length 320 /* Length of the cbits table */
+
+/* Offsets of the various tables from the base tables pointer, and
+total length. */
+
+#define lcc_offset 0
+#define fcc_offset 256
+#define cbits_offset 512
+#define ctypes_offset (cbits_offset + cbit_length)
+#define tables_length (ctypes_offset + 256)
+
+/* Internal function prefix */
+
+#ifdef COMPILE_PCRE8
+#ifndef PUBL
+#define PUBL(name) pcre_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre_##name
+#endif
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+#ifndef PUBL
+#define PUBL(name) pcre16_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre16_##name
+#endif
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+
+/* Layout of the UCP type table that translates property names into types and
+codes. Each entry used to point directly to a name, but to reduce the number of
+relocations in shared libraries, it now has an offset into a single string
+instead. */
+
+typedef struct {
+ pcre_uint16 name_offset;
+ pcre_uint16 type;
+ pcre_uint16 value;
+} ucp_type_table;
+
+
+/* Internal shared data tables. These are tables that are used by more than one
+of the exported public functions. They have to be "external" in the C sense,
+but are not part of the PCRE public API. The data for these tables is in the
+pcre_tables.c module. */
+
+#ifdef COMPILE_PCRE8
+
+extern const int PRIV(utf8_table1)[];
+extern const int PRIV(utf8_table1_size);
+extern const int PRIV(utf8_table2)[];
+extern const int PRIV(utf8_table3)[];
+extern const pcre_uint8 PRIV(utf8_table4)[];
+
+#endif /* COMPILE_PCRE8 */
+
+extern const char PRIV(utt_names)[];
+extern const ucp_type_table PRIV(utt)[];
+extern const int PRIV(utt_size);
+
+extern const pcre_uint8 PRIV(default_tables)[];
+
+extern const pcre_uint8 PRIV(OP_lengths)[];
+
+
+/* Internal shared functions. These are functions that are used by more than
+one of the exported public functions. They have to be "external" in the C
+sense, but are not part of the PCRE public API. */
+
+/* String comparison functions. */
+#ifdef COMPILE_PCRE8
+
+#define STRCMP_UC_UC(str1, str2) \
+ strcmp((char *)(str1), (char *)(str2))
+#define STRCMP_UC_C8(str1, str2) \
+ strcmp((char *)(str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ strncmp((char *)(str1), (char *)(str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ strncmp((char *)(str1), (str2), (num))
+#define STRLEN_UC(str) strlen((const char *)str)
+
+#else
+
+extern int PRIV(strcmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *);
+extern int PRIV(strcmp_uc_c8)(const pcre_uchar *,
+ const char *);
+extern int PRIV(strncmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *, unsigned int num);
+extern int PRIV(strncmp_uc_c8)(const pcre_uchar *,
+ const char *, unsigned int num);
+extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str);
+
+#define STRCMP_UC_UC(str1, str2) \
+ PRIV(strcmp_uc_uc)((str1), (str2))
+#define STRCMP_UC_C8(str1, str2) \
+ PRIV(strcmp_uc_c8)((str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ PRIV(strncmp_uc_uc)((str1), (str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ PRIV(strncmp_uc_c8)((str1), (str2), (num))
+#define STRLEN_UC(str) PRIV(strlen_uc)(str)
+
+#endif /* COMPILE_PCRE8 */
+
+extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
+extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
+extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
+extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL);
+
+#ifdef SUPPORT_JIT
+extern void PRIV(jit_compile)(const REAL_PCRE *, PUBL(extra) *);
+extern int PRIV(jit_exec)(const REAL_PCRE *, void *,
+ const pcre_uchar *, int, int, int, int, int *, int);
+extern void PRIV(jit_free)(void *);
+extern int PRIV(jit_get_size)(void *);
+extern const char* PRIV(jit_get_target)(void);
+#endif
+
+/* Unicode character database (UCD) */
+
+typedef struct {
+ pcre_uint8 script;
+ pcre_uint8 chartype;
+ pcre_int32 other_case;
+} ucd_record;
+
+extern const ucd_record PRIV(ucd_records)[];
+extern const pcre_uint8 PRIV(ucd_stage1)[];
+extern const pcre_uint16 PRIV(ucd_stage2)[];
+extern const int PRIV(ucp_gentype)[];
+#ifdef SUPPORT_JIT
+extern const int PRIV(ucp_typerange)[];
+#endif
+
+#ifdef SUPPORT_UCP
+/* UCD access macros */
+
+#define UCD_BLOCK_SIZE 128
+#define GET_UCD(ch) (PRIV(ucd_records) + \
+ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \
+ UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE])
+
+#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
+#define UCD_SCRIPT(ch) GET_UCD(ch)->script
+#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
+#define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case)
+
+#endif /* SUPPORT_UCP */
+
+#endif
+
+/* End of pcre_internal.h */
diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c
new file mode 100644
index 0000000000..f3d240d100
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_jit_compile.c
@@ -0,0 +1,6915 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+ The machine code generator part (this module) was written by Zoltan Herczeg
+ Copyright (c) 2010-2012
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifdef SUPPORT_JIT
+
+/* All-in-one: Since we use the JIT compiler only from here,
+we just include it. This way we don't need to touch the build
+system files. */
+
+#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
+#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
+#define SLJIT_CONFIG_AUTO 1
+#define SLJIT_CONFIG_STATIC 1
+#define SLJIT_VERBOSE 0
+#define SLJIT_DEBUG 0
+
+#include "sljit/sljitLir.c"
+
+#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
+#error Unsupported architecture
+#endif
+
+/* Allocate memory on the stack. Fast, but limited size. */
+#define LOCAL_SPACE_SIZE 32768
+
+#define STACK_GROWTH_RATE 8192
+
+/* Enable to check that the allocation could destroy temporaries. */
+#if defined SLJIT_DEBUG && SLJIT_DEBUG
+#define DESTROY_REGISTERS 1
+#endif
+
+/*
+Short summary about the backtracking mechanism empolyed by the jit code generator:
+
+The code generator follows the recursive nature of the PERL compatible regular
+expressions. The basic blocks of regular expressions are condition checkers
+whose execute different commands depending on the result of the condition check.
+The relationship between the operators can be horizontal (concatenation) and
+vertical (sub-expression) (See struct fallback_common for more details).
+
+ 'ab' - 'a' and 'b' regexps are concatenated
+ 'a+' - 'a' is the sub-expression of the '+' operator
+
+The condition checkers are boolean (true/false) checkers. Machine code is generated
+for the checker itself and for the actions depending on the result of the checker.
+The 'true' case is called as the hot path (expected path), and the other is called as
+the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken
+branches on the hot path.
+
+ Greedy star operator (*) :
+ Hot path: match happens.
+ Fallback path: match failed.
+ Non-greedy star operator (*?) :
+ Hot path: no need to perform a match.
+ Fallback path: match is required.
+
+The following example shows how the code generated for a capturing bracket
+with two alternatives. Let A, B, C, D are arbirary regular expressions, and
+we have the following regular expression:
+
+ A(B|C)D
+
+The generated code will be the following:
+
+ A hot path
+ '(' hot path (pushing arguments to the stack)
+ B hot path
+ ')' hot path (pushing arguments to the stack)
+ D hot path
+ return with successful match
+
+ D fallback path
+ ')' fallback path (If we arrived from "C" jump to the fallback of "C")
+ B fallback path
+ C expected path
+ jump to D hot path
+ C fallback path
+ A fallback path
+
+ Notice, that the order of fallback code paths are the opposite of the fast
+ code paths. In this way the topmost value on the stack is always belong
+ to the current fallback code path. The fallback code path must check
+ whether there is a next alternative. If so, it needs to jump back to
+ the hot path eventually. Otherwise it needs to clear out its own stack
+ frame and continue the execution on the fallback code paths.
+*/
+
+/*
+Saved stack frames:
+
+Atomic blocks and asserts require reloading the values of local variables
+when the fallback mechanism performed. Because of OP_RECURSE, the locals
+are not necessarly known in compile time, thus we need a dynamic restore
+mechanism.
+
+The stack frames are stored in a chain list, and have the following format:
+([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
+
+Thus we can restore the locals to a particular point in the stack.
+*/
+
+typedef struct jit_arguments {
+ /* Pointers first. */
+ struct sljit_stack *stack;
+ const pcre_uchar *str;
+ const pcre_uchar *begin;
+ const pcre_uchar *end;
+ int *offsets;
+ pcre_uchar *ptr;
+ /* Everything else after. */
+ int offsetcount;
+ int calllimit;
+ pcre_uint8 notbol;
+ pcre_uint8 noteol;
+ pcre_uint8 notempty;
+ pcre_uint8 notempty_atstart;
+} jit_arguments;
+
+typedef struct executable_function {
+ void *executable_func;
+ PUBL(jit_callback) callback;
+ void *userdata;
+ sljit_uw executable_size;
+} executable_function;
+
+typedef struct jump_list {
+ struct sljit_jump *jump;
+ struct jump_list *next;
+} jump_list;
+
+enum stub_types { stack_alloc };
+
+typedef struct stub_list {
+ enum stub_types type;
+ int data;
+ struct sljit_jump *start;
+ struct sljit_label *leave;
+ struct stub_list *next;
+} stub_list;
+
+typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+
+/* The following structure is the key data type for the recursive
+code generator. It is allocated by compile_hotpath, and contains
+the aguments for compile_fallbackpath. Must be the first member
+of its descendants. */
+typedef struct fallback_common {
+ /* Concatenation stack. */
+ struct fallback_common *prev;
+ jump_list *nextfallbacks;
+ /* Internal stack (for component operators). */
+ struct fallback_common *top;
+ jump_list *topfallbacks;
+ /* Opcode pointer. */
+ pcre_uchar *cc;
+} fallback_common;
+
+typedef struct assert_fallback {
+ fallback_common common;
+ jump_list *condfailed;
+ /* Less than 0 (-1) if a frame is not needed. */
+ int framesize;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* For iterators. */
+ struct sljit_label *hotpath;
+} assert_fallback;
+
+typedef struct bracket_fallback {
+ fallback_common common;
+ /* Where to coninue if an alternative is successfully matched. */
+ struct sljit_label *althotpath;
+ /* For rmin and rmax iterators. */
+ struct sljit_label *recursivehotpath;
+ /* For greedy ? operator. */
+ struct sljit_label *zerohotpath;
+ /* Contains the branches of a failed condition. */
+ union {
+ /* Both for OP_COND, OP_SCOND. */
+ jump_list *condfailed;
+ assert_fallback *assert;
+ /* For OP_ONCE. -1 if not needed. */
+ int framesize;
+ } u;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+} bracket_fallback;
+
+typedef struct bracketpos_fallback {
+ fallback_common common;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* Reverting stack is needed. */
+ int framesize;
+ /* Allocated stack size. */
+ int stacksize;
+} bracketpos_fallback;
+
+typedef struct braminzero_fallback {
+ fallback_common common;
+ struct sljit_label *hotpath;
+} braminzero_fallback;
+
+typedef struct iterator_fallback {
+ fallback_common common;
+ /* Next iteration. */
+ struct sljit_label *hotpath;
+} iterator_fallback;
+
+typedef struct recurse_entry {
+ struct recurse_entry *next;
+ /* Contains the function entry. */
+ struct sljit_label *entry;
+ /* Collects the calls until the function is not created. */
+ jump_list *calls;
+ /* Points to the starting opcode. */
+ int start;
+} recurse_entry;
+
+typedef struct recurse_fallback {
+ fallback_common common;
+} recurse_fallback;
+
+typedef struct compiler_common {
+ struct sljit_compiler *compiler;
+ pcre_uchar *start;
+ int localsize;
+ int *localptrs;
+ const pcre_uint8 *fcc;
+ sljit_w lcc;
+ int cbraptr;
+ int nltype;
+ int newline;
+ int bsr_nltype;
+ int endonly;
+ sljit_w ctypes;
+ sljit_uw name_table;
+ sljit_w name_count;
+ sljit_w name_entry_size;
+ struct sljit_label *acceptlabel;
+ stub_list *stubs;
+ recurse_entry *entries;
+ recurse_entry *currententry;
+ jump_list *accept;
+ jump_list *calllimit;
+ jump_list *stackalloc;
+ jump_list *revertframes;
+ jump_list *wordboundary;
+ jump_list *anynewline;
+ jump_list *hspace;
+ jump_list *vspace;
+ jump_list *casefulcmp;
+ jump_list *caselesscmp;
+ BOOL jscript_compat;
+#ifdef SUPPORT_UTF
+ BOOL utf;
+#ifdef SUPPORT_UCP
+ BOOL use_ucp;
+#endif
+ jump_list *utfreadchar;
+#ifdef COMPILE_PCRE8
+ jump_list *utfreadtype8;
+#endif
+#endif /* SUPPORT_UTF */
+#ifdef SUPPORT_UCP
+ jump_list *getucd;
+#endif
+} compiler_common;
+
+/* For byte_sequence_compare. */
+
+typedef struct compare_context {
+ int length;
+ int sourcereg;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ int ucharptr;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } c;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } oc;
+#endif
+} compare_context;
+
+enum {
+ frame_end = 0,
+ frame_setstrbegin = -1
+};
+
+/* Undefine sljit macros. */
+#undef CMP
+
+/* Used for accessing the elements of the stack. */
+#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w))
+
+#define TMP1 SLJIT_TEMPORARY_REG1
+#define TMP2 SLJIT_TEMPORARY_REG3
+#define TMP3 SLJIT_TEMPORARY_EREG2
+#define STR_PTR SLJIT_SAVED_REG1
+#define STR_END SLJIT_SAVED_REG2
+#define STACK_TOP SLJIT_TEMPORARY_REG2
+#define STACK_LIMIT SLJIT_SAVED_REG3
+#define ARGUMENTS SLJIT_SAVED_EREG1
+#define CALL_COUNT SLJIT_SAVED_EREG2
+#define RETURN_ADDR SLJIT_TEMPORARY_EREG1
+
+/* Locals layout. */
+/* These two locals can be used by the current opcode. */
+#define LOCALS0 (0 * sizeof(sljit_w))
+#define LOCALS1 (1 * sizeof(sljit_w))
+/* Two local variables for possessive quantifiers (char1 cannot use them). */
+#define POSSESSIVE0 (2 * sizeof(sljit_w))
+#define POSSESSIVE1 (3 * sizeof(sljit_w))
+/* Head of the last recursion. */
+#define RECURSIVE_HEAD (4 * sizeof(sljit_w))
+/* Max limit of recursions. */
+#define CALL_LIMIT (5 * sizeof(sljit_w))
+/* Last known position of the requested byte. */
+#define REQ_CHAR_PTR (6 * sizeof(sljit_w))
+/* End pointer of the first line. */
+#define FIRSTLINE_END (7 * sizeof(sljit_w))
+/* The output vector is stored on the stack, and contains pointers
+to characters. The vector data is divided into two groups: the first
+group contains the start / end character pointers, and the second is
+the start pointers when the end of the capturing group has not yet reached. */
+#define OVECTOR_START (8 * sizeof(sljit_w))
+#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w))
+#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w))
+#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start])
+
+#ifdef COMPILE_PCRE8
+#define MOV_UCHAR SLJIT_MOV_UB
+#define MOVU_UCHAR SLJIT_MOVU_UB
+#else
+#ifdef COMPILE_PCRE16
+#define MOV_UCHAR SLJIT_MOV_UH
+#define MOVU_UCHAR SLJIT_MOVU_UH
+#else
+#error Unsupported compiling mode
+#endif
+#endif
+
+/* Shortcuts. */
+#define DEFINE_COMPILER \
+ struct sljit_compiler *compiler = common->compiler
+#define OP1(op, dst, dstw, src, srcw) \
+ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
+#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
+ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
+#define LABEL() \
+ sljit_emit_label(compiler)
+#define JUMP(type) \
+ sljit_emit_jump(compiler, (type))
+#define JUMPTO(type, label) \
+ sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
+#define JUMPHERE(jump) \
+ sljit_set_label((jump), sljit_emit_label(compiler))
+#define CMP(type, src1, src1w, src2, src2w) \
+ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
+#define CMPTO(type, src1, src1w, src2, src2w, label) \
+ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
+#define COND_VALUE(op, dst, dstw, type) \
+ sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
+
+static pcre_uchar* bracketend(pcre_uchar* cc)
+{
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do cc += GET(cc, 1); while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+/* Functions whose might need modification for all new supported opcodes:
+ next_opcode
+ get_localspace
+ set_localptrs
+ get_framesize
+ init_frame
+ get_localsize
+ copy_locals
+ compile_hotpath
+ compile_fallbackpath
+*/
+
+static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
+{
+SLJIT_UNUSED_ARG(common);
+switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_DEF:
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_SKIPZERO:
+ return cc + 1;
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (common->utf) return NULL;
+#endif
+ return cc + 1;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSUPTO:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSUPTOI:
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_NOTPROP:
+ case OP_PROP:
+ return cc + 1 + 2;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ case OP_REF:
+ case OP_REFI:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_CLOSE:
+ cc += 1 + IMM2_SIZE;
+ return cc;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ return cc + 1 + 2 * IMM2_SIZE;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ return cc + 1 + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ return cc + GET(cc, 1);
+#endif
+
+ case OP_RECURSE:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_REVERSE:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return cc + 1 + LINK_SIZE;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ return cc + 1 + LINK_SIZE + IMM2_SIZE;
+
+ default:
+ return NULL;
+ }
+}
+
+static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localspace = 0;
+pcre_uchar *alternative;
+/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ if (cc == NULL)
+ return -1;
+ break;
+ }
+ }
+return localspace;
+}
+
+static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
+{
+pcre_uchar *cc = common->start;
+pcre_uchar *alternative;
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+}
+
+/* Returns with -1 if no need for frame. */
+static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
+{
+pcre_uchar *ccend = bracketend(cc);
+int length = 0;
+BOOL possessive = FALSE;
+BOOL setsom_found = FALSE;
+
+if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+ {
+ length = 3;
+ possessive = TRUE;
+ }
+
+cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ case OP_RECURSE:
+ if (!setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ length += 3;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+/* Possessive quantifiers can use a special case. */
+if (SLJIT_UNLIKELY(possessive) && length == 3)
+ return -1;
+
+if (length > 0)
+ return length + 1;
+return -1;
+}
+
+static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
+{
+DEFINE_COMPILER;
+pcre_uchar *ccend = bracketend(cc);
+BOOL setsom_found = FALSE;
+int offset;
+
+/* >= 1 + shortest item size (2) */
+SLJIT_UNUSED_ARG(stacktop);
+SLJIT_ASSERT(stackpos >= stacktop + 2);
+
+stackpos = STACK(stackpos);
+if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+ cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ case OP_RECURSE:
+ if (!setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setsom_found = TRUE;
+ }
+ cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos += (int)sizeof(sljit_w);
+
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
+SLJIT_ASSERT(stackpos == STACK(stacktop));
+}
+
+static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localsize = 2;
+pcre_uchar *alternative;
+/* Calculate the sum of the local variables. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ localsize++;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localsize += 2;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+SLJIT_ASSERT(cc == ccend);
+return localsize;
+}
+
+static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
+ BOOL save, int stackptr, int stacktop)
+{
+DEFINE_COMPILER;
+int srcw[2];
+int count;
+BOOL tmp1next = TRUE;
+BOOL tmp1empty = TRUE;
+BOOL tmp2empty = TRUE;
+pcre_uchar *alternative;
+enum {
+ start,
+ loop,
+ end
+} status;
+
+status = save ? start : loop;
+stackptr = STACK(stackptr - 2);
+stacktop = STACK(stacktop - 1);
+
+if (!save)
+ {
+ stackptr += sizeof(sljit_w);
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp1empty = FALSE;
+ }
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp2empty = FALSE;
+ }
+ /* The tmp1next must be TRUE in either way. */
+ }
+
+while (status != end)
+ {
+ count = 0;
+ switch(status)
+ {
+ case start:
+ SLJIT_ASSERT(save);
+ count = 1;
+ srcw[0] = RECURSIVE_HEAD;
+ status = loop;
+ break;
+
+ case loop:
+ if (cc >= ccend)
+ {
+ status = end;
+ break;
+ }
+
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ count = 1;
+ srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ count = 2;
+ srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ break;
+
+ case end:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ while (count > 0)
+ {
+ count--;
+ if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp1empty = FALSE;
+ tmp1next = FALSE;
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp2empty = FALSE;
+ tmp1next = TRUE;
+ }
+ }
+ else
+ {
+ if (tmp1next)
+ {
+ SLJIT_ASSERT(!tmp1empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
+ tmp1empty = stackptr >= stacktop;
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = FALSE;
+ }
+ else
+ {
+ SLJIT_ASSERT(!tmp2empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
+ tmp2empty = stackptr >= stacktop;
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = TRUE;
+ }
+ }
+ }
+ }
+
+if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ }
+SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
+}
+
+static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
+{
+return (value & (value - 1)) == 0;
+}
+
+static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
+{
+while (list)
+ {
+ /* sljit_set_label is clever enough to do nothing
+ if either the jump or the label is NULL */
+ sljit_set_label(list->jump, label);
+ list = list->next;
+ }
+}
+
+static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
+{
+jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
+if (list_item)
+ {
+ list_item->next = *list;
+ list_item->jump = jump;
+ *list = list_item;
+ }
+}
+
+static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
+{
+DEFINE_COMPILER;
+stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
+
+if (list_item)
+ {
+ list_item->type = type;
+ list_item->data = data;
+ list_item->start = start;
+ list_item->leave = LABEL();
+ list_item->next = common->stubs;
+ common->stubs = list_item;
+ }
+}
+
+static void flush_stubs(compiler_common *common)
+{
+DEFINE_COMPILER;
+stub_list* list_item = common->stubs;
+
+while (list_item)
+ {
+ JUMPHERE(list_item->start);
+ switch(list_item->type)
+ {
+ case stack_alloc:
+ add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
+ break;
+ }
+ JUMPTO(SLJIT_JUMP, list_item->leave);
+ list_item = list_item->next;
+ }
+common->stubs = NULL;
+}
+
+static SLJIT_INLINE void decrease_call_count(compiler_common *common)
+{
+DEFINE_COMPILER;
+
+OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
+add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
+}
+
+static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
+{
+/* May destroy all locals and registers except TMP2. */
+DEFINE_COMPILER;
+
+OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+#ifdef DESTROY_REGISTERS
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
+OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#endif
+add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
+}
+
+static SLJIT_INLINE void free_stack(compiler_common *common, int size)
+{
+DEFINE_COMPILER;
+OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+}
+
+static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+int i;
+/* At this point we can freely use all temporary registers. */
+/* TMP1 returns with begin - 1. */
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
+if (length < 8)
+ {
+ for (i = 0; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
+ }
+else
+ {
+ OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, loop);
+ }
+}
+
+static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *earlyexit;
+
+/* At this point we can freely use all registers. */
+OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
+
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
+/* Unlikely, but possible */
+earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
+loop = LABEL();
+OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
+OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
+/* Copy the integer value to the output buffer */
+#ifdef COMPILE_PCRE16
+OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
+#endif
+OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+JUMPTO(SLJIT_C_NOT_ZERO, loop);
+JUMPHERE(earlyexit);
+
+/* Calculate the return value, which is the maximum ovector value. */
+if (topbracket > 1)
+ {
+ OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
+
+ /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
+ OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
+ }
+else
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+}
+
+static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character has an othercase. */
+unsigned int c;
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return c != UCD_OTHERCASE(c);
+#else
+ return FALSE;
+#endif
+ }
+#ifndef COMPILE_PCRE8
+ return common->fcc[c] != c;
+#endif
+ }
+else
+#endif
+ c = *cc;
+return MAX_255(c) ? common->fcc[c] != c : FALSE;
+}
+
+static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
+{
+/* Returns with the othercase. */
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return UCD_OTHERCASE(c);
+#else
+ return c;
+#endif
+ }
+#endif
+return TABLE_GET(c, common->fcc, c);
+}
+
+static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character and its othercase has only 1 bit difference. */
+unsigned int c, oc, bit;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int n;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c <= 127)
+ oc = common->fcc[c];
+ else
+ {
+#ifdef SUPPORT_UCP
+ oc = UCD_OTHERCASE(c);
+#else
+ oc = c;
+#endif
+ }
+ }
+else
+ {
+ c = *cc;
+ oc = TABLE_GET(c, common->fcc, c);
+ }
+#else
+c = *cc;
+oc = TABLE_GET(c, common->fcc, c);
+#endif
+
+SLJIT_ASSERT(c != oc);
+
+bit = c ^ oc;
+/* Optimized for English alphabet. */
+if (c <= 127 && bit == 0x20)
+ return (0 << 8) | 0x20;
+
+/* Since c != oc, they must have at least 1 bit difference. */
+if (!ispowerof2(bit))
+ return 0;
+
+#ifdef COMPILE_PCRE8
+
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+ n = GET_EXTRALEN(*cc);
+ while ((bit & 0x3f) == 0)
+ {
+ n--;
+ bit >>= 6;
+ }
+ return (n << 8) | bit;
+ }
+#endif /* SUPPORT_UTF */
+return (0 << 8) | bit;
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+#ifdef SUPPORT_UTF
+if (common->utf && c > 65535)
+ {
+ if (bit >= (1 << 10))
+ bit >>= 10;
+ else
+ return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
+ }
+#endif /* SUPPORT_UTF */
+return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+}
+
+static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+}
+
+static void read_char(compiler_common *common)
+{
+/* Reads the character into TMP1, updates STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+ }
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void peek_char(compiler_common *common)
+{
+/* Reads the character into TMP1, keeps STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+static void read_char8_type(compiler_common *common)
+{
+/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+struct sljit_jump *jump;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ /* This can be an extra read in some situations, but hopefully
+ it is needed in most cases. */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+#else
+#ifdef COMPILE_PCRE16
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ JUMPHERE(jump);
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+#endif
+#endif /* COMPILE_PCRE8 */
+ return;
+ }
+#endif
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE16
+/* The ctypes array contains only 256 values. */
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+#ifdef COMPILE_PCRE16
+JUMPHERE(jump);
+#endif
+}
+
+static void skip_char_back(compiler_common *common)
+{
+/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+struct sljit_label *label;
+
+if (common->utf)
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
+ return;
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ return;
+ }
+#endif
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
+{
+/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
+DEFINE_COMPILER;
+
+if (nltype == NLTYPE_ANY)
+ {
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else if (nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else
+ {
+ SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
+ add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+}
+
+#ifdef SUPPORT_UTF
+
+#ifdef COMPILE_PCRE8
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Three byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* Four byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadtype8(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_jump *compare;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(compare);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* We only have types for characters less than 256. */
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
+of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
+/* Do nothing, only return. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+/* Combine two 16 bit characters. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+
+#ifdef SUPPORT_UCP
+
+/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
+#define UCD_BLOCK_MASK 127
+#define UCD_BLOCK_SHIFT 7
+
+static void do_getucd(compiler_common *common)
+{
+/* Search the UCD record for the character comes in TMP1.
+Returns chartype in TMP1 and UCD offset in TMP2. */
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
+OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif
+
+static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *mainloop;
+struct sljit_label *newlinelabel = NULL;
+struct sljit_jump *start;
+struct sljit_jump *end = NULL;
+struct sljit_jump *nl = NULL;
+#ifdef SUPPORT_UTF
+struct sljit_jump *singlechar;
+#endif
+jump_list *newline = NULL;
+BOOL newlinecheck = FALSE;
+BOOL readuchar = FALSE;
+
+if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
+ common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
+ newlinecheck = TRUE;
+
+if (firstline)
+ {
+ /* Search for the end of the first line. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ mainloop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ {
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ mainloop = LABEL();
+ /* Continual stores does not cause data dependency. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
+ read_char(common);
+ check_newlinechar(common, common->nltype, &newline, TRUE);
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
+ set_jumps(newline, LABEL());
+ }
+
+ JUMPHERE(end);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ }
+
+start = JUMP(SLJIT_JUMP);
+
+if (newlinecheck)
+ {
+ newlinelabel = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ nl = JUMP(SLJIT_JUMP);
+ }
+
+mainloop = LABEL();
+
+/* Increasing the STR_PTR here requires one less jump in the most common case. */
+#ifdef SUPPORT_UTF
+if (common->utf) readuchar = TRUE;
+#endif
+if (newlinecheck) readuchar = TRUE;
+
+if (readuchar)
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+if (newlinecheck)
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+JUMPHERE(start);
+
+if (newlinecheck)
+ {
+ JUMPHERE(end);
+ JUMPHERE(nl);
+ }
+
+return mainloop;
+}
+
+static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+pcre_uchar oc, bit;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+oc = first_char;
+if (caseless)
+ {
+ oc = TABLE_GET(first_char, common->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (first_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(first_char);
+#endif
+ }
+if (first_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
+else
+ {
+ bit = first_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
+ }
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ found = JUMP(SLJIT_C_NOT_ZERO);
+ }
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *lastchar;
+struct sljit_jump *firstchar;
+struct sljit_jump *leave;
+struct sljit_jump *foundcr = NULL;
+struct sljit_jump *notfoundnl;
+jump_list *newline = NULL;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(leave);
+ JUMPHERE(firstchar);
+ JUMPHERE(lastchar);
+
+ if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ return;
+ }
+
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+skip_char_back(common);
+
+loop = LABEL();
+read_char(common);
+lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+check_newlinechar(common, common->nltype, &newline, FALSE);
+set_jumps(newline, loop);
+
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ {
+ leave = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(notfoundnl);
+ JUMPHERE(leave);
+ }
+JUMPHERE(lastchar);
+JUMPHERE(firstchar);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+#ifndef COMPILE_PCRE8
+struct sljit_jump *jump;
+#endif
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#endif
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
+JUMPHERE(jump);
+#endif
+OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
+OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+found = JUMP(SLJIT_C_NOT_ZERO);
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *toolong;
+struct sljit_jump *alreadyfound;
+struct sljit_jump *found;
+struct sljit_jump *foundoc = NULL;
+struct sljit_jump *notfound;
+pcre_uchar oc, bit;
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
+OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
+toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
+alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
+
+if (has_firstchar)
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+else
+ OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
+
+loop = LABEL();
+notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+oc = req_char;
+if (caseless)
+ {
+ oc = TABLE_GET(req_char, common->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (req_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(req_char);
+#endif
+ }
+if (req_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+else
+ {
+ bit = req_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
+ }
+ else
+ {
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+ foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ }
+ }
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_JUMP, loop);
+
+JUMPHERE(found);
+if (foundoc)
+ JUMPHERE(foundoc);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
+JUMPHERE(alreadyfound);
+JUMPHERE(toolong);
+return notfound;
+}
+
+static void do_revertframes(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *mainloop;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
+
+/* Drop frames until we reach STACK_TOP. */
+mainloop = LABEL();
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+/* End of dropping frames. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
+/* Set string begin. */
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+/* Unknown command. */
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+}
+
+static void check_wordboundary(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *beginend;
+#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
+/* Get type of the previous char, and put it to LOCALS1. */
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
+beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+skip_char_back(common);
+read_char(common);
+
+/* Testing char type. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ /* Here LOCALS1 has already been zeroed. */
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif /* COMPILE_PCRE8 */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(beginend);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+peek_char(common);
+
+/* Testing char type. This is a code duplication. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ /* TMP2 may be destroyed by peek_char. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(beginend);
+
+OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+}
+
+static void check_anynewline(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_hspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_vspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define CHAR1 STR_END
+#define CHAR2 STACK_TOP
+
+static void do_casefulcmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define LCC_TABLE STACK_LIMIT
+
+static void do_caselesscmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
+OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+#endif
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#undef LCC_TABLE
+#undef CHAR1
+#undef CHAR2
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+
+static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
+{
+/* This function would be ineffective to do in JIT level. */
+int c1, c2;
+const pcre_uchar *src2 = args->ptr;
+const pcre_uchar *end2 = args->end;
+
+while (src1 < end1)
+ {
+ if (src2 >= end2)
+ return 0;
+ GETCHARINC(c1, src1);
+ GETCHARINC(c2, src2);
+ if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;
+ }
+return src2;
+}
+
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+
+static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
+ compare_context* context, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+unsigned int othercasebit = 0;
+pcre_uchar *othercasechar = NULL;
+#ifdef SUPPORT_UTF
+int utflength;
+#endif
+
+if (caseless && char_has_othercase(common, cc))
+ {
+ othercasebit = char_get_othercase_bit(common, cc);
+ SLJIT_ASSERT(othercasebit);
+ /* Extracting bit difference info. */
+#ifdef COMPILE_PCRE8
+ othercasechar = cc + (othercasebit >> 8);
+ othercasebit &= 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ othercasechar = cc + (othercasebit >> 9);
+ if ((othercasebit & 0x100) != 0)
+ othercasebit = (othercasebit & 0xff) << 8;
+ else
+ othercasebit &= 0xff;
+#endif
+#endif
+ }
+
+if (context->sourcereg == -1)
+ {
+#ifdef COMPILE_PCRE8
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+#ifdef COMPILE_PCRE16
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+#endif /* COMPILE_PCRE8 */
+ context->sourcereg = TMP2;
+ }
+
+#ifdef SUPPORT_UTF
+utflength = 1;
+if (common->utf && HAS_EXTRALEN(*cc))
+ utflength += GET_EXTRALEN(*cc);
+
+do
+ {
+#endif
+
+ context->length -= IN_UCHARS(1);
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+
+ /* Unaligned read is supported. */
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ context->c.asuchars[context->ucharptr] = *cc | othercasebit;
+ context->oc.asuchars[context->ucharptr] = othercasebit;
+ }
+ else
+ {
+ context->c.asuchars[context->ucharptr] = *cc;
+ context->oc.asuchars[context->ucharptr] = 0;
+ }
+ context->ucharptr++;
+
+#ifdef COMPILE_PCRE8
+ if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
+#else
+ if (context->ucharptr >= 2 || context->length == 0)
+#endif
+ {
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#ifdef COMPILE_PCRE8
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 1)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ switch(context->ucharptr)
+ {
+ case 4 / sizeof(pcre_uchar):
+ if (context->oc.asint != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
+ break;
+
+ case 2 / sizeof(pcre_uchar):
+ if (context->oc.asushort != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
+ break;
+
+#ifdef COMPILE_PCRE8
+ case 1:
+ if (context->oc.asbyte != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
+ break;
+#endif
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ context->ucharptr = 0;
+ }
+
+#else
+
+ /* Unaligned read is unsupported. */
+#ifdef COMPILE_PCRE8
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
+ }
+ else
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
+
+#endif
+
+ cc++;
+#ifdef SUPPORT_UTF
+ utflength--;
+ }
+while (utflength > 0);
+#endif
+
+return cc;
+}
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+
+#define SET_TYPE_OFFSET(value) \
+ if ((value) != typeoffset) \
+ { \
+ if ((value) > typeoffset) \
+ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
+ else \
+ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
+ } \
+ typeoffset = (value);
+
+#define SET_CHAR_OFFSET(value) \
+ if ((value) != charoffset) \
+ { \
+ if ((value) > charoffset) \
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
+ else \
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
+ } \
+ charoffset = (value);
+
+static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+jump_list *found = NULL;
+jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;
+unsigned int c;
+int compares;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin;
+#ifdef SUPPORT_UCP
+BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
+BOOL charsaved = FALSE;
+int typereg = TMP1, scriptreg = TMP1;
+unsigned int typeoffset;
+#endif
+int invertcmp, numberofcmps;
+unsigned int charoffset;
+
+/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
+check_input_end(common, fallbacks);
+read_char(common);
+
+if ((*cc++ & XCL_MAP) != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
+
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ JUMPHERE(jump);
+#endif
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#ifdef SUPPORT_UCP
+ charsaved = TRUE;
+#endif
+ cc += 32 / sizeof(pcre_uchar);
+ }
+
+/* Scanning the necessary info. */
+ccbegin = cc;
+compares = 0;
+while (*cc != XCL_END)
+ {
+ compares++;
+ if (*cc == XCL_SINGLE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ cc++;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ break;
+
+ case PT_LAMP:
+ case PT_GC:
+ case PT_PC:
+ case PT_ALNUM:
+ needstype = TRUE;
+ break;
+
+ case PT_SC:
+ needsscript = TRUE;
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ case PT_WORD:
+ needstype = TRUE;
+ needschar = TRUE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += 2;
+ }
+#endif
+ }
+
+#ifdef SUPPORT_UCP
+/* Simple register allocation. TMP1 is preferred if possible. */
+if (needstype || needsscript)
+ {
+ if (needschar && !charsaved)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ if (needschar)
+ {
+ if (needstype)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+ typereg = RETURN_ADDR;
+ }
+
+ if (needsscript)
+ scriptreg = TMP3;
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ }
+ else if (needstype && needsscript)
+ scriptreg = TMP3;
+ /* In all other cases only one of them was specified, and that can goes to TMP1. */
+
+ if (needsscript)
+ {
+ if (scriptreg == TMP1)
+ {
+ OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
+ }
+ else
+ {
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
+ }
+ }
+ }
+#endif
+
+/* Generating code. */
+cc = ccbegin;
+charoffset = 0;
+numberofcmps = 0;
+#ifdef SUPPORT_UCP
+typeoffset = 0;
+#endif
+
+while (*cc != XCL_END)
+ {
+ compares--;
+ invertcmp = (compares == 0 && list != fallbacks);
+ jump = NULL;
+
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ SET_CHAR_OFFSET(c);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ if (*cc == XCL_NOTPROP)
+ invertcmp ^= 0x1;
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ if (list != fallbacks)
+ {
+ if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
+ continue;
+ }
+ else if (cc[-1] == XCL_NOTPROP)
+ continue;
+ jump = JUMP(SLJIT_JUMP);
+ break;
+
+ case PT_LAMP:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_GC:
+ c = PRIV(ucp_typerange)[(int)cc[1] * 2];
+ SET_TYPE_OFFSET(c);
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
+ break;
+
+ case PT_PC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
+ break;
+
+ case PT_SC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ if (*cc == PT_SPACE)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
+ }
+ SET_CHAR_OFFSET(9);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ if (*cc == PT_SPACE)
+ JUMPHERE(jump);
+
+ SET_TYPE_OFFSET(ucp_Zl);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_WORD:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ /* ... fall through */
+
+ case PT_ALNUM:
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ SET_TYPE_OFFSET(ucp_Nd);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+ }
+ cc += 2;
+ }
+#endif
+
+ if (jump != NULL)
+ add_jump(compiler, compares > 0 ? list : fallbacks, jump);
+ }
+
+if (found != NULL)
+ set_jumps(found, LABEL());
+}
+
+#undef SET_TYPE_OFFSET
+#undef SET_CHAR_OFFSET
+
+#endif
+
+static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+int length;
+unsigned int c, oc, bit;
+compare_context context;
+struct sljit_jump *jump[4];
+#ifdef SUPPORT_UTF
+struct sljit_label *label;
+#ifdef SUPPORT_UCP
+pcre_uchar propdata[5];
+#endif
+#endif
+
+switch(type)
+ {
+ case OP_SOD:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+ add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
+ add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
+ add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_ANY:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[0]);
+ }
+ else
+ check_newlinechar(common, common->nltype, fallbacks, TRUE);
+ return cc;
+
+ case OP_ALLANY:
+ check_input_end(common, fallbacks);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+ JUMPHERE(jump[0]);
+ return cc;
+ }
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+ case OP_ANYBYTE:
+ check_input_end(common, fallbacks);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ case OP_NOTPROP:
+ case OP_PROP:
+ propdata[0] = 0;
+ propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
+ propdata[2] = cc[0];
+ propdata[3] = cc[1];
+ propdata[4] = XCL_END;
+ compile_xclass_hotpath(common, propdata, fallbacks);
+ return cc + 2;
+#endif
+#endif
+
+ case OP_ANYNL:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[3] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[0]);
+ check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ return cc;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+#ifdef SUPPORT_UCP
+ case OP_EXTUNI:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
+
+ label = LABEL();
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ JUMPHERE(jump[0]);
+ return cc;
+#endif
+
+ case OP_EODN:
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else if (common->nltype == NLTYPE_FIXED)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ jump[2] = JUMP(SLJIT_C_GREATER);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
+ /* Equal. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
+
+ JUMPHERE(jump[1]);
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+ }
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_EOD:
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ return cc;
+
+ case OP_CIRC:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ return cc;
+
+ case OP_CIRCM:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ skip_char_back(common);
+ read_char(common);
+ check_newlinechar(common, common->nltype, fallbacks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_DOLL:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+
+ if (!common->endonly)
+ compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
+ else
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
+ return cc;
+
+ case OP_DOLLM:
+ jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ peek_char(common);
+ check_newlinechar(common, common->nltype, fallbacks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
+#endif
+ if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
+ {
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.length = IN_UCHARS(length);
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
+ }
+ check_input_end(common, fallbacks);
+ read_char(common);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHAR(c, cc);
+ }
+ else
+#endif
+ c = *cc;
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+ return cc + length;
+
+ case OP_NOT:
+ case OP_NOTI:
+ check_input_end(common, fallbacks);
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ c = *cc;
+ if (c < 128)
+ {
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
+ }
+ /* Skip the variable-length character. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(jump[0]);
+ return cc + 1;
+ }
+ else
+#endif /* COMPILE_PCRE8 */
+ {
+ GETCHARLEN(c, cc, length);
+ read_char(common);
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ read_char(common);
+ c = *cc;
+ }
+
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ oc = char_othercase(common, c);
+ bit = c ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ }
+ else
+ {
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ }
+ }
+ return cc + 1;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ check_input_end(common, fallbacks);
+ read_char(common);
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ jump[0] = NULL;
+#ifdef COMPILE_PCRE8
+ /* This check only affects 8 bit mode. In other modes, we
+ always need to compare the value with 255. */
+ if (common->utf)
+#endif /* COMPILE_PCRE8 */
+ {
+ jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, fallbacks, jump[0]);
+ jump[0] = NULL;
+ }
+ }
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (jump[0] != NULL)
+ JUMPHERE(jump[0]);
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ return cc + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
+ return cc + GET(cc, 0) - 1;
+#endif
+
+ case OP_REVERSE:
+ length = GET(cc, 0);
+ SLJIT_ASSERT(length > 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
+ label = LABEL();
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
+ skip_char_back(common);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, label);
+ return cc + LINK_SIZE;
+ }
+#endif
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
+ return cc + LINK_SIZE;
+ }
+SLJIT_ASSERT_STOP();
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)
+{
+/* This function consumes at least one input character. */
+/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
+DEFINE_COMPILER;
+pcre_uchar *ccbegin = cc;
+compare_context context;
+int size;
+
+context.length = 0;
+do
+ {
+ if (cc >= ccend)
+ break;
+
+ if (*cc == OP_CHAR)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+#endif
+ }
+ else if (*cc == OP_CHARI)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ else if (HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+ }
+ else
+#endif
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ }
+ else
+ size = 0;
+
+ cc += 1 + size;
+ context.length += IN_UCHARS(size);
+ }
+while (size > 0 && context.length <= 128);
+
+cc = ccbegin;
+if (context.length > 0)
+ {
+ /* We have a fixed-length byte sequence. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);
+ return cc;
+ }
+
+/* A non-fixed length character will be checked if length == 0. */
+return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
+}
+
+static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+if (!common->jscript_compat)
+ {
+ if (fallbacks == NULL)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ return JUMP(SLJIT_C_NOT_ZERO);
+ }
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ }
+return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+}
+
+/* Forward definitions. */
+static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
+static void compile_fallbackpath(compiler_common *, struct fallback_common *);
+
+#define PUSH_FALLBACK(size, ccstart, error) \
+ do \
+ { \
+ fallback = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return error; \
+ memset(fallback, 0, size); \
+ fallback->prev = parent->top; \
+ fallback->cc = (ccstart); \
+ parent->top = fallback; \
+ } \
+ while (0)
+
+#define PUSH_FALLBACK_NOVALUE(size, ccstart) \
+ do \
+ { \
+ fallback = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ memset(fallback, 0, size); \
+ fallback->prev = parent->top; \
+ fallback->cc = (ccstart); \
+ parent->top = fallback; \
+ } \
+ while (0)
+
+#define FALLBACK_AS(type) ((type*)fallback)
+
+static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+struct sljit_jump *jump = NULL;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+if (withchecks && !common->jscript_compat)
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+if (common->utf && *cc == OP_REFI)
+ {
+ SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ if (withchecks)
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
+
+ /* Needed to save important temporary registers. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+ }
+else
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
+ if (withchecks)
+ jump = JUMP(SLJIT_C_ZERO);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ }
+
+if (jump != NULL)
+ {
+ if (emptyfail)
+ add_jump(compiler, fallbacks, jump);
+ else
+ JUMPHERE(jump);
+ }
+return cc + 1 + IMM2_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar type;
+struct sljit_label *label;
+struct sljit_jump *zerolength;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin = cc;
+int min = 0, max = 0;
+BOOL minimize;
+
+PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
+
+type = cc[1 + IMM2_SIZE];
+minimize = (type & 0x1) != 0;
+switch(type)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ min = 0;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ max = 1;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1 + IMM2_SIZE + 1);
+ max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
+ cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+if (!minimize)
+ {
+ if (min == 0)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ /* Temporary release of STR_PTR. */
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ /* Restore if not zero length. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
+ }
+
+ if (min > 1 || max > 1)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);
+
+ if (min > 1 || max > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ if (min > 1)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
+ if (max > 1)
+ {
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ JUMPHERE(jump);
+ }
+ }
+
+ if (max == 0)
+ {
+ /* Includes min > 1 case as well. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+
+ JUMPHERE(zerolength);
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+
+ decrease_call_count(common);
+ return cc;
+ }
+
+allocate_stack(common, 2);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+if (type != OP_CRMINSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+
+if (min == 0)
+ {
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ jump = JUMP(SLJIT_JUMP);
+ }
+else
+ zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
+
+FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+if (max > 0)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
+
+compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+if (min > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);
+ }
+else if (max > 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+
+if (jump != NULL)
+ JUMPHERE(jump);
+JUMPHERE(zerolength);
+
+decrease_call_count(common);
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+recurse_entry *entry = common->entries;
+recurse_entry *prev = NULL;
+int start = GET(cc, 1);
+
+PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);
+while (entry != NULL)
+ {
+ if (entry->start == start)
+ break;
+ prev = entry;
+ entry = entry->next;
+ }
+
+if (entry == NULL)
+ {
+ entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ entry->next = NULL;
+ entry->entry = NULL;
+ entry->calls = NULL;
+ entry->start = start;
+
+ if (prev != NULL)
+ prev->next = entry;
+ else
+ common->entries = entry;
+ }
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+allocate_stack(common, 1);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+
+if (entry->entry == NULL)
+ add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
+else
+ JUMPTO(SLJIT_FAST_CALL, entry->entry);
+/* Leave if the match is failed. */
+add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
+return cc + 1 + LINK_SIZE;
+}
+
+static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)
+{
+DEFINE_COMPILER;
+int framesize;
+int localptr;
+fallback_common altfallback;
+pcre_uchar *ccbegin;
+pcre_uchar opcode;
+pcre_uchar bra = OP_BRA;
+jump_list *tmp = NULL;
+jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
+jump_list **found;
+/* Saving previous accept variables. */
+struct sljit_label *save_acceptlabel = common->acceptlabel;
+struct sljit_jump *jump;
+struct sljit_jump *brajump = NULL;
+jump_list *save_accept = common->accept;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ SLJIT_ASSERT(!conditional);
+ bra = *cc;
+ cc++;
+ }
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+framesize = get_framesize(common, cc, FALSE);
+fallback->framesize = framesize;
+fallback->localptr = localptr;
+opcode = *cc;
+SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
+found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
+ccbegin = cc;
+cc += GET(cc, 1);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a braminzero fallback path. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+else
+ {
+ allocate_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, framesize + 1, 2, FALSE);
+ }
+
+memset(&altfallback, 0, sizeof(fallback_common));
+while (1)
+ {
+ common->acceptlabel = NULL;
+ common->accept = NULL;
+ altfallback.top = NULL;
+ altfallback.topfallbacks = NULL;
+
+ if (*ccbegin == OP_ALT)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ altfallback.cc = ccbegin;
+ compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->acceptlabel = save_acceptlabel;
+ common->accept = save_accept;
+ return NULL;
+ }
+ common->acceptlabel = LABEL();
+ if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+ /* Reset stack. */
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else {
+ if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ }
+
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ if (conditional)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (bra == OP_BRAZERO)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (framesize >= 0)
+ {
+ /* For OP_BRA and OP_BRAMINZERO. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ }
+ add_jump(compiler, found, JUMP(SLJIT_JUMP));
+
+ compile_fallbackpath(common, altfallback.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->acceptlabel = save_acceptlabel;
+ common->accept = save_accept;
+ return NULL;
+ }
+ set_jumps(altfallback.topfallbacks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ ccbegin = cc;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+
+if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
+ {
+ /* Assert is failed. */
+ if (conditional || bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ if (framesize < 0)
+ {
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ jump = JUMP(SLJIT_JUMP);
+ if (bra != OP_BRAZERO)
+ add_jump(compiler, target, jump);
+
+ /* Assert is successful. */
+ set_jumps(tmp, LABEL());
+ if (framesize < 0)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ /* Keep the STR_PTR on the top of the stack. */
+ if (bra == OP_BRAZERO)
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ else if (bra == OP_BRAMINZERO)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ else
+ {
+ if (bra == OP_BRA)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
+ }
+ }
+
+ if (bra == OP_BRAZERO)
+ {
+ fallback->hotpath = LABEL();
+ sljit_set_label(jump, fallback->hotpath);
+ }
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, fallback->hotpath);
+ JUMPHERE(brajump);
+ if (framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ set_jumps(fallback->common.topfallbacks, LABEL());
+ }
+ }
+else
+ {
+ /* AssertNot is successful. */
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra != OP_BRA)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra != OP_BRA)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+
+ if (bra == OP_BRAZERO)
+ fallback->hotpath = LABEL();
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, fallback->hotpath);
+ JUMPHERE(brajump);
+ }
+
+ if (bra != OP_BRA)
+ {
+ SLJIT_ASSERT(found == &fallback->common.topfallbacks);
+ set_jumps(fallback->common.topfallbacks, LABEL());
+ fallback->common.topfallbacks = NULL;
+ }
+ }
+
+common->acceptlabel = save_acceptlabel;
+common->accept = save_accept;
+return cc + 1 + LINK_SIZE;
+}
+
+static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w no_capture;
+int i;
+
+locals += OVECTOR_START / sizeof(sljit_w);
+no_capture = locals[1];
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == refno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate names
+ for different numbers are allowed, but not vice versa. First scan down
+ for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
+int i;
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == recno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate
+ names for different numbers are allowed, but not vice versa. First
+ scan down for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+/*
+ Handling bracketed expressions is probably the most complex part.
+
+ Stack layout naming characters:
+ S - Push the current STR_PTR
+ 0 - Push a 0 (NULL)
+ A - Push the current STR_PTR. Needed for restoring the STR_PTR
+ before the next alternative. Not pushed if there are no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+ C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
+ L - Push the previous local (pointed by localptr) to the stack
+ () - opional values stored on the stack
+ ()* - optonal, can be stored multiple times
+
+ The following list shows the regular expression templates, their PCRE byte codes
+ and stack layout supported by pcre-sljit.
+
+ (?:) OP_BRA | OP_KET A M
+ () OP_CBRA | OP_KET C M
+ (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
+ (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
+ ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
+ ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
+ (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
+ (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
+ ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
+ ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
+ (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
+ OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
+ (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
+ OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
+ ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
+ OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
+ ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
+ OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
+
+
+ Stack layout naming characters:
+ A - Push the alternative index (starting from 0) on the stack.
+ Not pushed if there is no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+
+ The next list shows the possible content of a bracket:
+ (|) OP_*BRA | OP_ALT ... M A
+ (?()|) OP_*COND | OP_ALT M A
+ (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
+ (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
+ Or nothing, if trace is unnecessary
+*/
+
+static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+int localptr = 0;
+int offset = 0;
+int stacksize;
+pcre_uchar *ccbegin;
+pcre_uchar *hotpath;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_fallback *assert;
+BOOL has_alternatives;
+struct sljit_jump *jump;
+struct sljit_jump *skip;
+struct sljit_label *rmaxlabel = NULL;
+struct sljit_jump *braminzerojump = NULL;
+
+PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ opcode = *cc;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+hotpath = ccbegin + 1 + LINK_SIZE;
+
+if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
+ {
+ /* Drop this bracket_fallback. */
+ parent->top = fallback->prev;
+ return bracketend(cc);
+ }
+
+ket = *(bracketend(cc) - 1 - LINK_SIZE);
+SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
+SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
+cc += GET(cc, 1);
+
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
+ if (*hotpath == OP_NRREF)
+ {
+ stacksize = GET2(hotpath, 1);
+ if (common->currententry == NULL || stacksize == RREF_ANY)
+ has_alternatives = FALSE;
+ else if (common->currententry->start == 0)
+ has_alternatives = stacksize != 0;
+ else
+ has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+ }
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Capturing brackets has a pre-allocated space. */
+ offset = GET2(ccbegin, 1 + LINK_SIZE);
+ localptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ FALLBACK_AS(bracket_fallback)->localptr = localptr;
+ hotpath += IMM2_SIZE;
+ }
+else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Other brackets simply allocate the next entry. */
+ localptr = PRIV_DATA(ccbegin);
+ SLJIT_ASSERT(localptr != 0);
+ FALLBACK_AS(bracket_fallback)->localptr = localptr;
+ if (opcode == OP_ONCE)
+ FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);
+ }
+
+/* Instructions before the first alternative. */
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ stacksize++;
+if (bra == OP_BRAZERO)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (ket != OP_KETRMIN)
+ {
+ free_stack(common, 1);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* Nothing stored during the first run. */
+ skip = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump);
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ /* When we come from outside, localptr contains the previous STR_PTR. */
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ }
+ else
+ {
+ /* Except when the whole stack frame must be saved. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));
+ }
+ JUMPHERE(skip);
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPHERE(jump);
+ }
+ }
+ }
+
+if (ket == OP_KETRMIN)
+ FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
+
+if (ket == OP_KETRMAX)
+ {
+ rmaxlabel = LABEL();
+ if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
+ FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;
+ }
+
+/* Handling capturing brackets and alternatives. */
+if (opcode == OP_ONCE)
+ {
+ if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ /* Neither capturing brackets nor recursions are not found in the block. */
+ if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else if (ket == OP_KETRMAX || has_alternatives)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ }
+ else
+ {
+ if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
+ {
+ allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);
+ }
+ else
+ {
+ allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);
+ }
+ }
+ }
+else if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Saving the previous values. */
+ allocate_stack(common, 3);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Saving the previous value. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+else if (has_alternatives)
+ {
+ /* Pushing the starting string pointer. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+/* Generating code for the first alternative. */
+if (opcode == OP_COND || opcode == OP_SCOND)
+ {
+ if (*hotpath == OP_CREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
+ CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ hotpath += 1 + IMM2_SIZE;
+ }
+ else if (*hotpath == OP_NCREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ stacksize = GET2(hotpath, 1);
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+
+ JUMPHERE(jump);
+ hotpath += 1 + IMM2_SIZE;
+ }
+ else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
+ {
+ /* Never has other case. */
+ FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
+
+ stacksize = GET2(hotpath, 1);
+ if (common->currententry == NULL)
+ stacksize = 0;
+ else if (stacksize == RREF_ANY)
+ stacksize = 1;
+ else if (common->currententry->start == 0)
+ stacksize = stacksize == 0;
+ else
+ stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+
+ if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
+ {
+ SLJIT_ASSERT(!has_alternatives);
+ if (stacksize != 0)
+ hotpath += 1 + IMM2_SIZE;
+ else
+ {
+ if (*cc == OP_ALT)
+ {
+ hotpath = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+ else
+ hotpath = cc;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives);
+
+ stacksize = GET2(hotpath, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+ hotpath += 1 + IMM2_SIZE;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
+ /* Similar code as PUSH_FALLBACK macro. */
+ assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ memset(assert, 0, sizeof(assert_fallback));
+ assert->common.cc = hotpath;
+ FALLBACK_AS(bracket_fallback)->u.assert = assert;
+ hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);
+ }
+ }
+
+compile_hotpath(common, hotpath, cc, fallback);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+if (opcode == OP_ONCE)
+ {
+ if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+stacksize = 0;
+if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+if (has_alternatives && opcode != OP_ONCE)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if (ket != OP_KET)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ stacksize++;
+ }
+else if (bra != OP_BRA)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (has_alternatives)
+ {
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ if (ket != OP_KETRMAX)
+ FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
+ }
+
+/* Must be after the hotpath label. */
+if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ if (has_alternatives)
+ FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE)
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
+ else
+ /* TMP2 must contain the starting STR_PTR. */
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, rmaxlabel);
+ FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
+ }
+
+if (bra == OP_BRAZERO)
+ FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
+ JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);
+ if (braminzerojump != NULL)
+ {
+ JUMPHERE(braminzerojump);
+ /* We need to release the end pointer to perform the
+ fallback for the zero-length iteration. When
+ framesize is < 0, OP_ONCE will do the release itself. */
+ if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ else if (ket == OP_KETRMIN && opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ /* Continue to the normal fallback. */
+ }
+
+if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
+ decrease_call_count(common);
+
+/* Skip the other alternatives. */
+while (*cc == OP_ALT)
+ cc += GET(cc, 1);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+int localptr;
+int cbraprivptr = 0;
+int framesize;
+int stacksize;
+int offset = 0;
+BOOL zero = FALSE;
+pcre_uchar *ccbegin = NULL;
+int stack;
+struct sljit_label *loop = NULL;
+struct jump_list *emptymatch = NULL;
+
+PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);
+if (*cc == OP_BRAPOSZERO)
+ {
+ zero = TRUE;
+ cc++;
+ }
+
+opcode = *cc;
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
+switch(opcode)
+ {
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ ccbegin = cc + 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ offset = GET2(cc, 1 + LINK_SIZE);
+ cbraprivptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+framesize = get_framesize(common, cc, FALSE);
+FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
+if (framesize < 0)
+ {
+ stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
+ if (!zero)
+ stacksize++;
+ FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
+ }
+else
+ {
+ stacksize = framesize + 1;
+ if (!zero)
+ stacksize++;
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ stacksize++;
+ FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ stack = 0;
+ if (!zero)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
+ stack++;
+ }
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
+ stack++;
+ }
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
+ init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
+ }
+
+if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+
+loop = LABEL();
+while (*cc != OP_KETRPOS)
+ {
+ fallback->top = NULL;
+ fallback->topfallbacks = NULL;
+ cc += GET(cc, 1);
+
+ compile_hotpath(common, ccbegin, cc, fallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ JUMPTO(SLJIT_JUMP, loop);
+ flush_stubs(common);
+
+ compile_fallbackpath(common, fallback->top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ set_jumps(fallback->topfallbacks, LABEL());
+
+ if (framesize < 0)
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ /* Last alternative. */
+ if (*cc == OP_KETRPOS)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ }
+ }
+
+ if (*cc == OP_KETRPOS)
+ break;
+ ccbegin = cc + 1 + LINK_SIZE;
+ }
+
+fallback->topfallbacks = NULL;
+if (!zero)
+ {
+ if (framesize < 0)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
+ else /* TMP2 is set to [localptr] above. */
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
+ }
+
+/* None of them matched. */
+set_jumps(emptymatch, LABEL());
+decrease_call_count(common);
+return cc + 1 + LINK_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
+{
+int class_len;
+
+*opcode = *cc;
+if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
+ {
+ cc++;
+ *type = OP_CHAR;
+ }
+else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
+ {
+ cc++;
+ *type = OP_CHARI;
+ *opcode -= OP_STARI - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
+ {
+ cc++;
+ *type = OP_NOT;
+ *opcode -= OP_NOTSTAR - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
+ {
+ cc++;
+ *type = OP_NOTI;
+ *opcode -= OP_NOTSTARI - OP_STAR;
+ }
+else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
+ {
+ cc++;
+ *opcode -= OP_TYPESTAR - OP_STAR;
+ *type = 0;
+ }
+else
+ {
+ SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
+ *type = *opcode;
+ cc++;
+ class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
+ *opcode = cc[class_len - 1];
+ if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
+ {
+ *opcode -= OP_CRSTAR - OP_STAR;
+ if (end != NULL)
+ *end = cc + class_len;
+ }
+ else
+ {
+ SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
+ *arg1 = GET2(cc, (class_len + IMM2_SIZE));
+ *arg2 = GET2(cc, class_len);
+
+ if (*arg2 == 0)
+ {
+ SLJIT_ASSERT(*arg1 != 0);
+ *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
+ }
+ if (*arg1 == *arg2)
+ *opcode = OP_EXACT;
+
+ if (end != NULL)
+ *end = cc + class_len + 2 * IMM2_SIZE;
+ }
+ return cc;
+ }
+
+if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
+ {
+ *arg1 = GET2(cc, 0);
+ cc += IMM2_SIZE;
+ }
+
+if (*type == 0)
+ {
+ *type = *cc;
+ if (end != NULL)
+ *end = next_opcode(common, cc);
+ cc++;
+ return cc;
+ }
+
+if (end != NULL)
+ {
+ *end = cc + 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
+#endif
+ }
+return cc;
+}
+
+static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+pcre_uchar* end;
+jump_list *nomatch = NULL;
+struct sljit_jump *jump = NULL;
+struct sljit_label *label;
+
+PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ if (opcode == OP_STAR || opcode == OP_UPTO)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ if (opcode == OP_CRRANGE && arg2 > 0)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
+ if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ }
+
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ if (jump != NULL)
+ JUMPHERE(jump);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
+ {
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_PLUS || opcode == OP_CRRANGE)
+ add_jump(compiler, &fallback->topfallbacks,
+ CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode == OP_MINPLUS)
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ if (opcode == OP_CRMINRANGE)
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_QUERY:
+ case OP_MINQUERY:
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode == OP_QUERY)
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_EXACT:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSUPTO:
+ if (opcode != OP_POSSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ if (opcode != OP_POSUPTO)
+ {
+ if (opcode == OP_POSPLUS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_POSPLUS)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ case OP_POSQUERY:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ set_jumps(nomatch, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+decrease_call_count(common);
+return end;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+
+PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
+
+if (*cc == OP_FAIL)
+ {
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ return cc + 1;
+ }
+
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
+ {
+ /* No need to check notempty conditions. */
+ if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->acceptlabel);
+ return cc + 1;
+ }
+
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+else
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
+add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+return cc + 1;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1);
+
+/* Data will be discarded anyway... */
+if (common->currententry != NULL)
+ return cc + 1 + IMM2_SIZE;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
+offset <<= 1;
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+return cc + 1 + IMM2_SIZE;
+}
+
+static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_REVERSE:
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+ case OP_SET_SOM:
+ PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ cc++;
+ break;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ cc = compile_iterator_hotpath(common, cc, parent);
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
+ cc = compile_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
+ cc = compile_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+#endif
+
+ case OP_REF:
+ case OP_REFI:
+ if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
+ cc = compile_ref_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
+ break;
+
+ case OP_RECURSE:
+ cc = compile_recurse_hotpath(common, cc, parent);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
+ cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
+ break;
+
+ case OP_BRAMINZERO:
+ PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);
+ cc = bracketend(cc + 1);
+ if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
+ }
+ FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ decrease_call_count(common);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ cc = compile_bracket_hotpath(common, cc, parent);
+ break;
+
+ case OP_BRAZERO:
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ cc = compile_bracket_hotpath(common, cc, parent);
+ else
+ {
+ PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
+ cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
+ }
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ cc = compile_bracketpos_hotpath(common, cc, parent);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ cc = compile_fail_accept_hotpath(common, cc, parent);
+ break;
+
+ case OP_CLOSE:
+ cc = compile_close_hotpath(common, cc);
+ break;
+
+ case OP_SKIPZERO:
+ cc = bracketend(cc + 1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return;
+ }
+ if (cc == NULL)
+ return;
+ }
+SLJIT_ASSERT(cc == ccend);
+}
+
+#undef PUSH_FALLBACK
+#undef PUSH_FALLBACK_NOVALUE
+#undef FALLBACK_AS
+
+#define COMPILE_FALLBACKPATH(current) \
+ do \
+ { \
+ compile_fallbackpath(common, (current)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ } \
+ while (0)
+
+#define CURRENT_AS(type) ((type*)current)
+
+static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+struct sljit_label *label = NULL;
+struct sljit_jump *jump = NULL;
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ }
+ else
+ {
+ if (opcode == OP_STAR || opcode == OP_UPTO)
+ arg2 = 0;
+ else if (opcode == OP_PLUS)
+ arg2 = 1;
+ jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ skip_char_back(common);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ if (opcode == OP_PLUS || opcode == OP_CRRANGE)
+ set_jumps(current->topfallbacks, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 2);
+ }
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (opcode == OP_MINPLUS)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ current->topfallbacks = NULL;
+ }
+ compile_char1_hotpath(common, type, cc, &current->topfallbacks);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, 1);
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ if (opcode == OP_CRMINRANGE)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ current->topfallbacks = NULL;
+ label = LABEL();
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ compile_char1_hotpath(common, type, cc, &current->topfallbacks);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+
+ if (opcode == OP_CRMINRANGE)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
+
+ if (opcode == OP_CRMINRANGE && arg1 == 0)
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ else
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath);
+
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, 2);
+ break;
+
+ case OP_QUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_MINQUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ compile_char1_hotpath(common, type, cc, &current->topfallbacks);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ set_jumps(current->topfallbacks, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_EXACT:
+ case OP_POSPLUS:
+ set_jumps(current->topfallbacks, LABEL());
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+}
+
+static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar type;
+
+type = cc[1 + IMM2_SIZE];
+if ((type & 0x1) == 0)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ return;
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+set_jumps(current->topfallbacks, LABEL());
+free_stack(common, 2);
+}
+
+static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+
+set_jumps(current->topfallbacks, LABEL());
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+free_stack(common, 1);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+}
+
+static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar bra = OP_BRA;
+struct sljit_jump *brajump = NULL;
+
+SLJIT_ASSERT(*cc != OP_BRAMINZERO);
+if (*cc == OP_BRAZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ SLJIT_ASSERT(current->topfallbacks == NULL);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+
+if (CURRENT_AS(assert_fallback)->framesize < 0)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
+ free_stack(common, 1);
+ }
+ return;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
+ free_stack(common, 1);
+ return;
+ }
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
+
+ set_jumps(current->topfallbacks, LABEL());
+ }
+else
+ set_jumps(current->topfallbacks, LABEL());
+
+if (bra == OP_BRAZERO)
+ {
+ /* We know there is enough place on the stack. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath);
+ JUMPHERE(brajump);
+ }
+}
+
+static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+int opcode;
+int offset = 0;
+int localptr = CURRENT_AS(bracket_fallback)->localptr;
+int stacksize;
+int count;
+pcre_uchar *cc = current->cc;
+pcre_uchar *ccbegin;
+pcre_uchar *ccprev;
+jump_list *jumplist = NULL;
+jump_list *jumplistitem = NULL;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_fallback *assert;
+BOOL has_alternatives;
+struct sljit_jump *brazero = NULL;
+struct sljit_jump *once = NULL;
+struct sljit_jump *cond = NULL;
+struct sljit_label *rminlabel = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
+cc += GET(cc, 1);
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (ket == OP_KETRMAX)
+ {
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ if (bra != OP_BRAMINZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (opcode >= OP_SBRA || opcode == OP_ONCE)
+ {
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0)
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath);
+ }
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ }
+ rminlabel = LABEL();
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_ONCE))
+ {
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ once = JUMP(SLJIT_JUMP);
+ }
+else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ if (has_alternatives)
+ {
+ /* Always exactly one alternative. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+ jumplist = jumplistitem;
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
+ }
+ }
+else if (*cc == OP_ALT)
+ {
+ /* Build a jump list. Get the last successfully matched branch index. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ count = 1;
+ do
+ {
+ /* Append as the last item. */
+ if (jumplist != NULL)
+ {
+ jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplistitem = jumplistitem->next;
+ }
+ else
+ {
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplist = jumplistitem;
+ }
+
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
+ cc += GET(cc, 1);
+ }
+ while (*cc == OP_ALT);
+
+ cc = ccbegin + GET(ccbegin, 1);
+ }
+
+COMPILE_FALLBACKPATH(current->top);
+if (current->topfallbacks)
+ set_jumps(current->topfallbacks, LABEL());
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ /* Conditional block always has at most one alternative. */
+ if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ assert = CURRENT_AS(bracket_fallback)->u.assert;
+ if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
+ }
+ else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
+ }
+ else
+ SLJIT_ASSERT(!has_alternatives);
+ }
+
+if (has_alternatives)
+ {
+ count = 1;
+ do
+ {
+ current->top = NULL;
+ current->topfallbacks = NULL;
+ current->nextfallbacks = NULL;
+ if (*cc == OP_ALT)
+ {
+ ccprev = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ if (opcode != OP_COND && opcode != OP_SCOND)
+ {
+ if (localptr != 0 && opcode != OP_ONCE)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ compile_hotpath(common, ccprev, cc, current);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ }
+
+ /* Instructions after the current alternative is succesfully matched. */
+ /* There is a similar code in compile_bracket_hotpath. */
+ if (opcode == OP_ONCE)
+ {
+ if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+ stacksize = 0;
+ if (opcode != OP_ONCE)
+ stacksize++;
+ if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+
+ if (stacksize > 0) {
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ allocate_stack(common, stacksize);
+ else
+ {
+ /* We know we have place at least for one item on the top of the stack. */
+ SLJIT_ASSERT(stacksize == 1);
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ }
+
+ stacksize = 0;
+ if (ket != OP_KET || bra != OP_BRA)
+ {
+ if (ket != OP_KET)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
+
+ if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath);
+
+ if (opcode != OP_ONCE)
+ {
+ SLJIT_ASSERT(jumplist);
+ JUMPHERE(jumplist->jump);
+ jumplist = jumplist->next;
+ }
+
+ COMPILE_FALLBACKPATH(current->top);
+ if (current->topfallbacks)
+ set_jumps(current->topfallbacks, LABEL());
+ SLJIT_ASSERT(!current->nextfallbacks);
+ }
+ while (*cc == OP_ALT);
+ SLJIT_ASSERT(!jumplist);
+
+ if (cond != NULL)
+ {
+ SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
+ assert = CURRENT_AS(bracket_fallback)->u.assert;
+ if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
+
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ JUMPHERE(cond);
+ }
+
+ /* Free the STR_PTR. */
+ if (localptr == 0)
+ free_stack(common, 1);
+ }
+
+if (offset != 0)
+ {
+ /* Using both tmp register is better for instruction scheduling. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
+ free_stack(common, 3);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ }
+else if (opcode == OP_ONCE)
+ {
+ cc = ccbegin + GET(ccbegin, 1);
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ /* Reset head and drop saved frame. */
+ stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
+ free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
+ }
+ else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
+ {
+ /* The STR_PTR must be released. */
+ free_stack(common, 1);
+ }
+
+ JUMPHERE(once);
+ /* Restore previous localptr */
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w));
+ else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* See the comment below. */
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
+ JUMPHERE(brazero);
+ }
+ free_stack(common, 1);
+ }
+else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ /* OP_ONCE removes everything in case of a fallback, so we don't
+ need to explicitly release the STR_PTR. The extra release would
+ affect badly the free_stack(2) above. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
+ if (opcode == OP_ONCE)
+ free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
+ else if (bra == OP_BRAMINZERO)
+ free_stack(common, 1);
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
+ JUMPHERE(brazero);
+ }
+}
+
+static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+int offset;
+struct sljit_jump *jump;
+
+if (CURRENT_AS(bracketpos_fallback)->framesize < 0)
+ {
+ if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
+ {
+ offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ }
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
+ return;
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr);
+add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+
+if (current->topfallbacks)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topfallbacks, LABEL());
+ /* Drop the stack frame. */
+ free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
+ JUMPHERE(jump);
+ }
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
+}
+
+static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+assert_fallback fallback;
+
+current->top = NULL;
+current->topfallbacks = NULL;
+current->nextfallbacks = NULL;
+if (current->cc[1] > OP_ASSERTBACK_NOT)
+ {
+ /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */
+ compile_bracket_hotpath(common, current->cc, current);
+ compile_bracket_fallbackpath(common, current->top);
+ }
+else
+ {
+ memset(&fallback, 0, sizeof(fallback));
+ fallback.common.cc = current->cc;
+ fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath;
+ /* Manual call of compile_assert_hotpath. */
+ compile_assert_hotpath(common, current->cc, &fallback, FALSE);
+ }
+SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks);
+}
+
+static void compile_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+
+while (current)
+ {
+ if (current->nextfallbacks != NULL)
+ set_jumps(current->nextfallbacks, LABEL());
+ switch(*current->cc)
+ {
+ case OP_SET_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
+ compile_iterator_fallbackpath(common, current);
+ break;
+
+ case OP_REF:
+ case OP_REFI:
+ compile_ref_iterator_fallbackpath(common, current);
+ break;
+
+ case OP_RECURSE:
+ compile_recurse_fallbackpath(common, current);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ compile_assert_fallbackpath(common, current);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ compile_bracket_fallbackpath(common, current);
+ break;
+
+ case OP_BRAZERO:
+ if (current->cc[1] > OP_ASSERTBACK_NOT)
+ compile_bracket_fallbackpath(common, current);
+ else
+ compile_assert_fallbackpath(common, current);
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ compile_bracketpos_fallbackpath(common, current);
+ break;
+
+ case OP_BRAMINZERO:
+ compile_braminzero_fallbackpath(common, current);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ set_jumps(current->topfallbacks, LABEL());
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ current = current->prev;
+ }
+}
+
+static SLJIT_INLINE void compile_recurse(compiler_common *common)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = common->start + common->currententry->start;
+pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
+pcre_uchar *ccend = bracketend(cc);
+int localsize = get_localsize(common, ccbegin, ccend);
+int framesize = get_framesize(common, cc, TRUE);
+int alternativesize;
+BOOL needsframe;
+fallback_common altfallback;
+struct sljit_jump *jump;
+
+SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
+needsframe = framesize >= 0;
+if (!needsframe)
+ framesize = 0;
+alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
+
+SLJIT_ASSERT(common->currententry->entry == NULL);
+common->currententry->entry = LABEL();
+set_jumps(common->currententry->calls, common->currententry->entry);
+
+sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize);
+allocate_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
+copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);
+if (needsframe)
+ init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
+
+if (alternativesize > 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+memset(&altfallback, 0, sizeof(fallback_common));
+common->acceptlabel = NULL;
+common->accept = NULL;
+altfallback.cc = ccbegin;
+cc += GET(cc, 1);
+while (1)
+ {
+ altfallback.top = NULL;
+ altfallback.topfallbacks = NULL;
+
+ if (altfallback.cc != ccbegin)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ compile_hotpath(common, altfallback.cc, cc, &altfallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+
+ compile_fallbackpath(common, altfallback.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ set_jumps(altfallback.topfallbacks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ altfallback.cc = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_JUMP);
+
+set_jumps(common->accept, LABEL());
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD);
+if (needsframe)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
+ }
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
+
+JUMPHERE(jump);
+copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
+free_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
+OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+}
+
+#undef COMPILE_FALLBACKPATH
+#undef CURRENT_AS
+
+void
+PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)
+{
+struct sljit_compiler *compiler;
+fallback_common rootfallback;
+compiler_common common_data;
+compiler_common *common = &common_data;
+const pcre_uint8 *tables = re->tables;
+pcre_study_data *study;
+pcre_uchar *ccend;
+executable_function *function;
+void *executable_func;
+sljit_uw executable_size;
+struct sljit_label *leave;
+struct sljit_label *mainloop = NULL;
+struct sljit_label *empty_match_found;
+struct sljit_label *empty_match_fallback;
+struct sljit_jump *alloc_error;
+struct sljit_jump *reqbyte_notfound = NULL;
+struct sljit_jump *empty_match;
+
+SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
+study = extra->study_data;
+
+if (!tables)
+ tables = PRIV(default_tables);
+
+memset(&rootfallback, 0, sizeof(fallback_common));
+rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
+
+common->compiler = NULL;
+common->start = rootfallback.cc;
+common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
+common->fcc = tables + fcc_offset;
+common->lcc = (sljit_w)(tables + lcc_offset);
+common->nltype = NLTYPE_FIXED;
+switch(re->options & PCRE_NEWLINE_BITS)
+ {
+ case 0:
+ /* Compile-time default */
+ switch (NEWLINE)
+ {
+ case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: common->newline = NEWLINE; break;
+ }
+ break;
+ case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: return;
+ }
+if ((re->options & PCRE_BSR_ANYCRLF) != 0)
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+else if ((re->options & PCRE_BSR_UNICODE) != 0)
+ common->bsr_nltype = NLTYPE_ANY;
+else
+ {
+#ifdef BSR_ANYCRLF
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+#else
+ common->bsr_nltype = NLTYPE_ANY;
+#endif
+ }
+common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+common->ctypes = (sljit_w)(tables + ctypes_offset);
+common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
+common->name_count = re->name_count;
+common->name_entry_size = re->name_entry_size;
+common->acceptlabel = NULL;
+common->stubs = NULL;
+common->entries = NULL;
+common->currententry = NULL;
+common->accept = NULL;
+common->calllimit = NULL;
+common->stackalloc = NULL;
+common->revertframes = NULL;
+common->wordboundary = NULL;
+common->anynewline = NULL;
+common->hspace = NULL;
+common->vspace = NULL;
+common->casefulcmp = NULL;
+common->caselesscmp = NULL;
+common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+common->utf = (re->options & PCRE_UTF8) != 0;
+#ifdef SUPPORT_UCP
+common->use_ucp = (re->options & PCRE_UCP) != 0;
+#endif
+common->utfreadchar = NULL;
+#ifdef COMPILE_PCRE8
+common->utfreadtype8 = NULL;
+#endif
+#endif /* SUPPORT_UTF */
+#ifdef SUPPORT_UCP
+common->getucd = NULL;
+#endif
+ccend = bracketend(rootfallback.cc);
+SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
+common->localsize = get_localspace(common, rootfallback.cc, ccend);
+if (common->localsize < 0)
+ return;
+common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
+if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
+ return;
+common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
+if (!common->localptrs)
+ return;
+memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
+set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
+
+compiler = sljit_create_compiler();
+if (!compiler)
+ {
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+common->compiler = compiler;
+
+/* Main pcre_jit_exec entry. */
+sljit_emit_enter(compiler, 1, 5, 5, common->localsize);
+
+/* Register init. */
+reset_ovector(common, (re->top_bracket + 1) * 2);
+if ((re->flags & PCRE_REQCHSET) != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);
+
+OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
+
+/* Main part of the matching */
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ /* Forward search if possible. */
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) != 0)
+ fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
+ fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
+ }
+if ((re->flags & PCRE_REQCHSET) != 0)
+ reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
+
+/* Store the current STR_PTR in OVECTOR(0). */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+/* Copy the limit of allowed recursions. */
+OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
+
+compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+empty_match_found = LABEL();
+
+common->acceptlabel = LABEL();
+if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+/* This means we have a match. Update the ovector. */
+copy_ovector(common, re->top_bracket + 1);
+leave = LABEL();
+sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
+
+empty_match_fallback = LABEL();
+compile_fallbackpath(common, rootfallback.top);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+SLJIT_ASSERT(rootfallback.prev == NULL);
+
+/* Check we have remaining characters. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ if ((re->options & PCRE_FIRSTLINE) == 0)
+ {
+ if (study != NULL && study->minlength > 1)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ }
+ else
+ {
+ if (study != NULL && study->minlength > 1)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+ JUMPTO(SLJIT_C_ZERO, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop);
+ }
+ }
+
+if (reqbyte_notfound != NULL)
+ JUMPHERE(reqbyte_notfound);
+/* Copy OVECTOR(1) to OVECTOR(0) */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+JUMPTO(SLJIT_JUMP, leave);
+
+flush_stubs(common);
+
+JUMPHERE(empty_match);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
+JUMPTO(SLJIT_JUMP, empty_match_fallback);
+
+common->currententry = common->entries;
+while (common->currententry != NULL)
+ {
+ /* Might add new entries. */
+ compile_recurse(common);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+ flush_stubs(common);
+ common->currententry = common->currententry->next;
+ }
+
+/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
+/* This is a (really) rare case. */
+set_jumps(common->stackalloc, LABEL());
+/* RETURN_ADDR is not a saved register. */
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
+OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
+
+sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+
+/* Allocation failed. */
+JUMPHERE(alloc_error);
+/* We break the return address cache here, but this is a really rare case. */
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
+JUMPTO(SLJIT_JUMP, leave);
+
+/* Call limit reached. */
+set_jumps(common->calllimit, LABEL());
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
+JUMPTO(SLJIT_JUMP, leave);
+
+if (common->revertframes != NULL)
+ {
+ set_jumps(common->revertframes, LABEL());
+ do_revertframes(common);
+ }
+if (common->wordboundary != NULL)
+ {
+ set_jumps(common->wordboundary, LABEL());
+ check_wordboundary(common);
+ }
+if (common->anynewline != NULL)
+ {
+ set_jumps(common->anynewline, LABEL());
+ check_anynewline(common);
+ }
+if (common->hspace != NULL)
+ {
+ set_jumps(common->hspace, LABEL());
+ check_hspace(common);
+ }
+if (common->vspace != NULL)
+ {
+ set_jumps(common->vspace, LABEL());
+ check_vspace(common);
+ }
+if (common->casefulcmp != NULL)
+ {
+ set_jumps(common->casefulcmp, LABEL());
+ do_casefulcmp(common);
+ }
+if (common->caselesscmp != NULL)
+ {
+ set_jumps(common->caselesscmp, LABEL());
+ do_caselesscmp(common);
+ }
+#ifdef SUPPORT_UTF
+if (common->utfreadchar != NULL)
+ {
+ set_jumps(common->utfreadchar, LABEL());
+ do_utfreadchar(common);
+ }
+#ifdef COMPILE_PCRE8
+if (common->utfreadtype8 != NULL)
+ {
+ set_jumps(common->utfreadtype8, LABEL());
+ do_utfreadtype8(common);
+ }
+#endif
+#endif /* COMPILE_PCRE8 */
+#ifdef SUPPORT_UCP
+if (common->getucd != NULL)
+ {
+ set_jumps(common->getucd, LABEL());
+ do_getucd(common);
+ }
+#endif
+
+SLJIT_FREE(common->localptrs);
+executable_func = sljit_generate_code(compiler);
+executable_size = sljit_get_generated_code_size(compiler);
+sljit_free_compiler(compiler);
+if (executable_func == NULL)
+ return;
+
+function = SLJIT_MALLOC(sizeof(executable_function));
+if (function == NULL)
+ {
+ /* This case is highly unlikely since we just recently
+ freed a lot of memory. Although not impossible. */
+ sljit_free_code(executable_func);
+ return;
+ }
+
+function->executable_func = executable_func;
+function->executable_size = executable_size;
+function->callback = NULL;
+function->userdata = NULL;
+extra->executable_jit = function;
+extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
+}
+
+static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)
+{
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+pcre_uint8 local_area[LOCAL_SPACE_SIZE];
+struct sljit_stack local_stack;
+
+local_stack.top = (sljit_w)&local_area;
+local_stack.base = local_stack.top;
+local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
+local_stack.max_limit = local_stack.limit;
+arguments->stack = &local_stack;
+convert_executable_func.executable_func = function->executable_func;
+return convert_executable_func.call_executable_func(arguments);
+}
+
+int
+PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,
+ const pcre_uchar *subject, int length, int start_offset, int options,
+ int match_limit, int *offsets, int offsetcount)
+{
+executable_function *function = (executable_function*)executable_func;
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+jit_arguments arguments;
+int maxoffsetcount;
+int retval;
+
+/* Sanity checks should be handled by pcre_exec. */
+arguments.stack = NULL;
+arguments.str = subject + start_offset;
+arguments.begin = subject;
+arguments.end = subject + length;
+arguments.calllimit = match_limit; /* JIT decreases this value less times. */
+arguments.notbol = (options & PCRE_NOTBOL) != 0;
+arguments.noteol = (options & PCRE_NOTEOL) != 0;
+arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
+arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+arguments.offsets = offsets;
+
+/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
+the output vector for storing captured strings, with the remainder used as
+workspace. We don't need the workspace here. For compatibility, we limit the
+number of captured strings in the same way as pcre_exec(), so that the user
+gets the same result with and without JIT. */
+
+if (offsetcount != 2)
+ offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
+maxoffsetcount = (re->top_bracket + 1) * 2;
+if (offsetcount > maxoffsetcount)
+ offsetcount = maxoffsetcount;
+arguments.offsetcount = offsetcount;
+
+if (function->callback)
+ arguments.stack = (struct sljit_stack*)function->callback(function->userdata);
+else
+ arguments.stack = (struct sljit_stack*)function->userdata;
+
+if (arguments.stack == NULL)
+ retval = jit_machine_stack_exec(&arguments, function);
+else
+ {
+ convert_executable_func.executable_func = function->executable_func;
+ retval = convert_executable_func.call_executable_func(&arguments);
+ }
+
+if (retval * 2 > offsetcount)
+ retval = 0;
+return retval;
+}
+
+void
+PRIV(jit_free)(void *executable_func)
+{
+executable_function *function = (executable_function*)executable_func;
+sljit_free_code(function->executable_func);
+SLJIT_FREE(function);
+}
+
+int
+PRIV(jit_get_size)(void *executable_func)
+{
+return ((executable_function*)executable_func)->executable_size;
+}
+
+const char*
+PRIV(jit_get_target)(void)
+{
+return sljit_get_platform_name();
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+if (startsize < 1 || maxsize < 1)
+ return NULL;
+if (startsize > maxsize)
+ startsize = maxsize;
+startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+sljit_free_stack((struct sljit_stack*)stack);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+executable_function *function;
+if (extra != NULL &&
+ (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ {
+ function = (executable_function*)extra->executable_jit;
+ function->callback = callback;
+ function->userdata = userdata;
+ }
+}
+
+#else /* SUPPORT_JIT */
+
+/* These are dummy functions to avoid linking errors when JIT support is not
+being compiled. */
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+(void)startsize;
+(void)maxsize;
+return NULL;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+(void)stack;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+(void)extra;
+(void)callback;
+(void)userdata;
+}
+
+#endif
+
+/* End of pcre_jit_compile.c */
diff --git a/src/3rdparty/pcre/pcre_maketables.c b/src/3rdparty/pcre/pcre_maketables.c
new file mode 100644
index 0000000000..caacdba3e6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_maketables.c
@@ -0,0 +1,148 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_maketables(), which builds
+character tables for PCRE in the current locale. The file is compiled on its
+own as part of the PCRE library. However, it is also included in the
+compilation of dftables.c, in which case the macro DFTABLES is defined. */
+
+
+#ifndef DFTABLES
+# ifdef PCRE_HAVE_CONFIG_H
+# include "config.h"
+# endif
+# include "pcre_internal.h"
+#endif
+
+
+/*************************************************
+* Create PCRE character tables *
+*************************************************/
+
+/* This function builds a set of character tables for use by PCRE and returns
+a pointer to them. They are build using the ctype functions, and consequently
+their contents will depend upon the current locale setting. When compiled as
+part of the library, the store is obtained via PUBL(malloc)(), but when
+compiled inside dftables, use malloc().
+
+Arguments: none
+Returns: pointer to the contiguous block of data
+*/
+
+#ifdef COMPILE_PCRE8
+const unsigned char *
+pcre_maketables(void)
+#else
+const unsigned char *
+pcre16_maketables(void)
+#endif
+{
+unsigned char *yield, *p;
+int i;
+
+#ifndef DFTABLES
+yield = (unsigned char*)(PUBL(malloc))(tables_length);
+#else
+yield = (unsigned char*)malloc(tables_length);
+#endif
+
+if (yield == NULL) return NULL;
+p = yield;
+
+/* First comes the lower casing table */
+
+for (i = 0; i < 256; i++) *p++ = tolower(i);
+
+/* Next the case-flipping table */
+
+for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
+
+/* Then the character class tables. Don't try to be clever and save effort on
+exclusive ones - in some locales things may be different. Note that the table
+for "space" includes everything "isspace" gives, including VT in the default
+locale. This makes it work for the POSIX class [:space:]. Note also that it is
+possible for a character to be alnum or alpha without being lower or upper,
+such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at
+least under Debian Linux's locales as of 12/2005). So we must test for alnum
+specially. */
+
+memset(p, 0, cbit_length);
+for (i = 0; i < 256; i++)
+ {
+ if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7);
+ if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7);
+ if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7);
+ if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7);
+ if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
+ if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
+ if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
+ if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
+ if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
+ if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
+ if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
+ }
+p += cbit_length;
+
+/* Finally, the character type table. In this, we exclude VT from the white
+space chars, because Perl doesn't recognize it as such for \s and for comments
+within regexes. */
+
+for (i = 0; i < 256; i++)
+ {
+ int x = 0;
+ if (i != 0x0b && isspace(i)) x += ctype_space;
+ if (isalpha(i)) x += ctype_letter;
+ if (isdigit(i)) x += ctype_digit;
+ if (isxdigit(i)) x += ctype_xdigit;
+ if (isalnum(i) || i == '_') x += ctype_word;
+
+ /* Note: strchr includes the terminating zero in the characters it considers.
+ In this instance, that is ok because we want binary zero to be flagged as a
+ meta-character, which in this sense is any character that terminates a run
+ of data characters. */
+
+ if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
+ *p++ = x;
+ }
+
+return yield;
+}
+
+/* End of pcre_maketables.c */
diff --git a/src/3rdparty/pcre/pcre_newline.c b/src/3rdparty/pcre/pcre_newline.c
new file mode 100644
index 0000000000..8ee2a6e588
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_newline.c
@@ -0,0 +1,184 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains internal functions for testing newlines when more than
+one kind of newline is to be recognized. When a newline is found, its length is
+returned. In principle, we could implement several newline "types", each
+referring to a different set of newline characters. At present, PCRE supports
+only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
+and NLTYPE_ANY. The full list of Unicode newline characters is taken from
+http://unicode.org/unicode/reports/tr18/. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+
+/*************************************************
+* Check for newline at given position *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is less than the end of the
+string that is being processed.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ endptr pointer to the end of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
+ BOOL utf)
+{
+int c;
+(void)utf;
+#ifdef SUPPORT_UTF
+if (utf)
+ {
+ GETCHAR(c, ptr);
+ }
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case 0x000a: *lenptr = 1; return TRUE; /* LF */
+ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+ return TRUE; /* CR */
+ default: return FALSE;
+ }
+
+/* NLTYPE_ANY */
+
+else switch(c)
+ {
+ case 0x000a: /* LF */
+ case 0x000b: /* VT */
+ case 0x000c: *lenptr = 1; return TRUE; /* FF */
+ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+ return TRUE; /* CR */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
+ default: return FALSE;
+ }
+}
+
+
+
+/*************************************************
+* Check for newline at previous position *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is greater than the start of
+the string that is being processed.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ startptr pointer to the start of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
+ BOOL utf)
+{
+int c;
+(void)utf;
+ptr--;
+#ifdef SUPPORT_UTF
+if (utf)
+ {
+ BACKCHAR(ptr);
+ GETCHAR(c, ptr);
+ }
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+ return TRUE; /* LF */
+ case 0x000d: *lenptr = 1; return TRUE; /* CR */
+ default: return FALSE;
+ }
+
+else switch(c)
+ {
+ case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+ return TRUE; /* LF */
+ case 0x000b: /* VT */
+ case 0x000c: /* FF */
+ case 0x000d: *lenptr = 1; return TRUE; /* CR */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
+ default: return FALSE;
+ }
+}
+
+/* End of pcre_newline.c */
diff --git a/src/3rdparty/pcre/pcre_ord2utf8.c b/src/3rdparty/pcre/pcre_ord2utf8.c
new file mode 100644
index 0000000000..6afd235f79
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_ord2utf8.c
@@ -0,0 +1,97 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF8 string. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Convert character value to UTF-8 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
+
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result - at least 6 pcre_uchars long
+
+Returns: number of characters placed in the buffer
+*/
+
+int
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
+{
+#ifdef SUPPORT_UTF
+
+register int i, j;
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+for (i = 0; i < PRIV(utf8_table1_size); i++)
+ if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
+buffer += i;
+for (j = i; j > 0; j--)
+ {
+ *buffer-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*buffer = PRIV(utf8_table2)[i] | cvalue;
+return i + 1;
+
+#else
+
+(void)(cvalue); /* Keep compiler happy; this function won't ever be */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
+return 0;
+
+#endif
+}
+
+/* End of pcre_ord2utf8.c */
diff --git a/src/3rdparty/pcre/pcre_refcount.c b/src/3rdparty/pcre/pcre_refcount.c
new file mode 100644
index 0000000000..263a1e11dc
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_refcount.c
@@ -0,0 +1,89 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_refcount(), which is an
+auxiliary function that can be used to maintain a reference count in a compiled
+pattern data block. This might be helpful in applications where the block is
+shared by different users. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Maintain reference count *
+*************************************************/
+
+/* The reference count is a 16-bit field, initialized to zero. It is not
+possible to transfer a non-zero count from one host to a different host that
+has a different byte order - though I can't see why anyone in their right mind
+would ever want to do that!
+
+Arguments:
+ argument_re points to compiled code
+ adjust value to add to the count
+
+Returns: the (possibly updated) count value (a non-negative number), or
+ a negative error number
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_refcount(pcre *argument_re, int adjust)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_refcount(pcre16 *argument_re, int adjust)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+re->ref_count = (-adjust > re->ref_count)? 0 :
+ (adjust + re->ref_count > 65535)? 65535 :
+ re->ref_count + adjust;
+return re->ref_count;
+}
+
+/* End of pcre_refcount.c */
diff --git a/src/3rdparty/pcre/pcre_string_utils.c b/src/3rdparty/pcre/pcre_string_utils.c
new file mode 100644
index 0000000000..d4545532a7
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_string_utils.c
@@ -0,0 +1,168 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifndef COMPILE_PCRE8
+
+/*************************************************
+* Compare string utilities *
+*************************************************/
+
+/* The following two functions compares two strings. Basically an strcmp
+for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *str2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *ustr2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following two functions compares two, fixed length
+strings. Basically an strncmp for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+ num size of the string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following function returns with the length of
+a zero terminated string. Basically an strlen for non 8 bit characters.
+
+Arguments:
+ str string
+
+Returns: length of the string
+*/
+
+unsigned int
+PRIV(strlen_uc)(const pcre_uchar *str)
+{
+unsigned int len = 0;
+while (*str++ != 0)
+ len++;
+return len;
+}
+
+#endif /* COMPILE_PCRE8 */
+
+/* End of pcre_string_utils.c */
diff --git a/src/3rdparty/pcre/pcre_study.c b/src/3rdparty/pcre/pcre_study.c
new file mode 100644
index 0000000000..6b6edc3f31
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_study.c
@@ -0,0 +1,1527 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_study(), along with local
+supporting functions. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#define SET_BIT(c) start_bits[c/8] |= (1 << (c&7))
+
+/* Returns from set_start_bits() */
+
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
+
+
+
+/*************************************************
+* Find the minimum subject length for a group *
+*************************************************/
+
+/* Scan a parenthesized group and compute the minimum length of subject that
+is needed to match it. This is a lower bound; it does not mean there is a
+string of that length that matches. In UTF8 mode, the result is in characters
+rather than bytes.
+
+Arguments:
+ code pointer to start of group (the bracket)
+ startcode pointer to start of the whole pattern
+ options the compiling options
+ int RECURSE depth
+
+Returns: the minimum length
+ -1 if \C in UTF-8 mode or (*ACCEPT) was encountered
+ -2 internal error (missing capturing bracket)
+ -3 internal error (opcode not listed)
+*/
+
+static int
+find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
+ int recurse_depth)
+{
+int length = -1;
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+BOOL had_recurse = FALSE;
+register int branchlength = 0;
+register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
+
+if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+ {
+ int d, min;
+ pcre_uchar *cs, *ce;
+ register int op = *cc;
+
+ switch (op)
+ {
+ case OP_COND:
+ case OP_SCOND:
+
+ /* If there is only one branch in a condition, the implied branch has zero
+ length, so we don't add anything. This covers the DEFINE "condition"
+ automatically. */
+
+ cs = cc + GET(cc, 1);
+ if (*cs != OP_ALT)
+ {
+ cc = cs + 1 + LINK_SIZE;
+ break;
+ }
+
+ /* Otherwise we can fall through and treat it the same as any other
+ subpattern. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ d = find_minlength(cc, startcode, options, recurse_depth);
+ if (d < 0) return d;
+ branchlength += d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* ACCEPT makes things far too complicated; we have to give up. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ return -1;
+
+ /* Reached end of a branch; if it's a ket it is the end of a nested
+ call. If it's ALT it is an alternation in a nested call. If it is END it's
+ the end of the outer call. All can be handled by the same code. If an
+ ACCEPT was previously encountered, use the length that was in force at that
+ time, and pass back the shortest ACCEPT length. */
+
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_END:
+ if (length < 0 || (!had_recurse && branchlength < length))
+ length = branchlength;
+ if (op != OP_ALT) return length;
+ cc += 1 + LINK_SIZE;
+ branchlength = 0;
+ had_recurse = FALSE;
+ break;
+
+ /* Skip over assertive subpatterns */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ /* Fall through */
+
+ /* Skip over things that don't match chars */
+
+ case OP_REVERSE:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ case OP_CALLOUT:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Skip over a subpattern that has a {0} or {0,x} quantifier */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_SKIPZERO:
+ cc += PRIV(OP_lengths)[*cc];
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Handle literal characters and + repetitions */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ branchlength++;
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ branchlength++;
+ cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
+ break;
+
+ /* Handle exact repetitions. The count is already in characters, but we
+ need to skip over a multibyte character in UTF8 mode. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEEXACT:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
+
+ /* Handle single-char non-literal matchers */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ cc += 2;
+ /* Fall through */
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_EXTUNI:
+ case OP_HSPACE:
+ case OP_NOT_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_VSPACE:
+ branchlength++;
+ cc++;
+ break;
+
+ /* "Any newline" might match two characters, but it also might match just
+ one. */
+
+ case OP_ANYNL:
+ branchlength += 1;
+ cc++;
+ break;
+
+ /* The single-byte matcher means we can't proceed in UTF-8 mode. (In
+ non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever
+ appear, but leave the code, just in case.) */
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (utf) return -1;
+#endif
+ branchlength++;
+ cc++;
+ break;
+
+ /* For repeated character types, we have to test for \p and \P, which have
+ an extra two bytes of parameters. */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSQUERY:
+ if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* Check a class for variable quantification */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
+ /* Fall through */
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ cc += PRIV(OP_lengths)[OP_CLASS];
+
+ switch (*cc)
+ {
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ branchlength++;
+ /* Fall through */
+
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ branchlength += GET2(cc,1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ branchlength++;
+ break;
+ }
+ break;
+
+ /* Backreferences and subroutine calls are treated in the same way: we find
+ the minimum length for the subpattern. A recursion, however, causes an
+ a flag to be set that causes the length of this branch to be ignored. The
+ logic is that a recursion can only make sense if there is another
+ alternation that stops the recursing. That will provide the minimum length
+ (when no recursion happens). A backreference within the group that it is
+ referencing behaves in the same way.
+
+ If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket
+ matches an empty string (by default it causes a matching failure), so in
+ that case we must set the minimum length to zero. */
+
+ case OP_REF:
+ case OP_REFI:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ {
+ ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce)
+ {
+ d = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ d = find_minlength(cs, startcode, options, recurse_depth);
+ }
+ }
+ else d = 0;
+ cc += 1 + IMM2_SIZE;
+
+ /* Handle repeated back references */
+
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ cc++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ min = 1;
+ break;
+ }
+
+ branchlength += min * d;
+ break;
+
+ /* We can easily detect direct recursion, but not mutual recursion. This is
+ caught by a recursion depth count. */
+
+ case OP_RECURSE:
+ cs = ce = (pcre_uchar *)startcode + GET(cc, 1);
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if ((cc > cs && cc < ce) || recurse_depth > 10)
+ had_recurse = TRUE;
+ else
+ {
+ branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Anything else does not or need not match a character. We can get the
+ item's length from the table, but for those that can match zero occurrences
+ of a character, we must take special action for UTF-8 characters. As it
+ happens, the "NOT" versions of these opcodes are used at present only for
+ ASCII characters, so they could be omitted from this list. However, in
+ future that may change, so we include them here so as not to leave a
+ gotcha for a future maintainer. */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+
+ cc += PRIV(OP_lengths)[op];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ /* Skip these, but we need to add in the name length. */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += PRIV(OP_lengths)[op] + cc[1];
+ break;
+
+ /* The remaining opcodes are just skipped over. */
+
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_PRUNE:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_THEN:
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* This should not occur: we list all opcodes explicitly so that when
+ new ones get added they are properly considered. */
+
+ default:
+ return -3;
+ }
+ }
+/* Control never gets here */
+}
+
+
+
+/*************************************************
+* Set a bit and maybe its alternate case *
+*************************************************/
+
+/* Given a character, set its first byte's bit in the table, and also the
+corresponding bit for the other version of a letter if we are caseless. In
+UTF-8 mode, for characters greater than 127, we can only do the caseless thing
+when Unicode property support is available.
+
+Arguments:
+ start_bits points to the bit map
+ p points to the character
+ caseless the caseless flag
+ cd the block with char table pointers
+ utf TRUE for UTF-8 / UTF-16 mode
+
+Returns: pointer after the character
+*/
+
+static const pcre_uchar *
+set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
+ compile_data *cd, BOOL utf)
+{
+unsigned int c = *p;
+
+#ifdef COMPILE_PCRE8
+SET_BIT(c);
+
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
+ {
+ GETCHARINC(c, p);
+#ifdef SUPPORT_UCP
+ if (caseless)
+ {
+ pcre_uchar buff[6];
+ c = UCD_OTHERCASE(c);
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+#endif
+ return p;
+ }
+#endif
+
+/* Not UTF-8 mode, or character is less than 127. */
+
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
+return p + 1;
+#endif
+
+#ifdef COMPILE_PCRE16
+if (c > 0xff)
+ {
+ c = 0xff;
+ caseless = FALSE;
+ }
+SET_BIT(c);
+
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
+ {
+ GETCHARINC(c, p);
+#ifdef SUPPORT_UCP
+ if (caseless)
+ {
+ c = UCD_OTHERCASE(c);
+ if (c > 0xff)
+ c = 0xff;
+ SET_BIT(c);
+ }
+#endif
+ return p;
+ }
+#endif
+
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
+return p + 1;
+#endif
+}
+
+
+
+/*************************************************
+* Set bits for a positive character type *
+*************************************************/
+
+/* This function sets starting bits for a character type. In UTF-8 mode, we can
+only do a direct setting for bytes less than 128, as otherwise there can be
+confusion with bytes in the middle of UTF-8 characters. In a "traditional"
+environment, the tables will only recognize ASCII characters anyway, but in at
+least one Windows environment, some higher bytes bits were set in the tables.
+So we deal with that case by considering the UTF-8 encoding.
+
+Arguments:
+ start_bits the starting bitmap
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+ cd the block with char table pointers
+
+Returns: nothing
+*/
+
+static void
+set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
+ compile_data *cd)
+{
+register int c;
+for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (table_limit == 32) return;
+for (c = 128; c < 256; c++)
+ {
+ if ((cd->cbits[c/8] & (1 << (c&7))) != 0)
+ {
+ pcre_uchar buff[6];
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+ }
+#endif
+}
+
+
+/*************************************************
+* Set bits for a negative character type *
+*************************************************/
+
+/* This function sets starting bits for a negative character type such as \D.
+In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
+otherwise there can be confusion with bytes in the middle of UTF-8 characters.
+Unlike in the positive case, where we can set appropriate starting bits for
+specific high-valued UTF-8 characters, in this case we have to set the bits for
+all high-valued characters. The lowest is 0xc2, but we overkill by starting at
+0xc0 (192) for simplicity.
+
+Arguments:
+ start_bits the starting bitmap
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+ cd the block with char table pointers
+
+Returns: nothing
+*/
+
+static void
+set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
+ compile_data *cd)
+{
+register int c;
+for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
+#endif
+}
+
+
+
+/*************************************************
+* Create bitmap of starting bytes *
+*************************************************/
+
+/* This function scans a compiled unanchored expression recursively and
+attempts to build a bitmap of the set of possible starting bytes. As time goes
+by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
+useful for parenthesized groups in patterns such as (a*)b where the group
+provides some optional starting bytes but scanning must continue at the outer
+level to find at least one mandatory byte. At the outermost level, this
+function fails unless the result is SSB_DONE.
+
+Arguments:
+ code points to an expression
+ start_bits points to a 32-byte table, initialized to 0
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd the block with char table pointers
+
+Returns: SSB_FAIL => Failed to find any starting bytes
+ SSB_DONE => Found mandatory starting bytes
+ SSB_CONTINUE => Found optional starting bytes
+ SSB_UNKNOWN => Hit an unrecognized opcode
+*/
+
+static int
+set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
+ compile_data *cd)
+{
+register int c;
+int yield = SSB_DONE;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int table_limit = utf? 16:32;
+#else
+int table_limit = 32;
+#endif
+
+#if 0
+/* ========================================================================= */
+/* The following comment and code was inserted in January 1999. In May 2006,
+when it was observed to cause compiler warnings about unused values, I took it
+out again. If anybody is still using OS/2, they will have to put it back
+manually. */
+
+/* This next statement and the later reference to dummy are here in order to
+trick the optimizer of the IBM C compiler for OS/2 into generating correct
+code. Apparently IBM isn't going to fix the problem, and we would rather not
+disable optimization (in this module it actually makes a big difference, and
+the pcre module can use all the optimization it can get). */
+
+volatile int dummy;
+/* ========================================================================= */
+#endif
+
+do
+ {
+ BOOL try_next = TRUE;
+ const pcre_uchar *tcode = code + 1 + LINK_SIZE;
+
+ if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
+
+ while (try_next) /* Loop for items in this branch */
+ {
+ int rc;
+
+ switch(*tcode)
+ {
+ /* If we reach something we don't understand, it means a new opcode has
+ been created that hasn't been added to this code. Hopefully this problem
+ will be discovered during testing. */
+
+ default:
+ return SSB_UNKNOWN;
+
+ /* Fail for a valid opcode that implies no starting bits. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_ALLANY:
+ case OP_ANY:
+ case OP_ANYBYTE:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_COND:
+ case OP_CREF:
+ case OP_DEF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_END:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_EXTUNI:
+ case OP_FAIL:
+ case OP_MARK:
+ case OP_NCREF:
+ case OP_NOT:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_NOTI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTPROP:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_NRREF:
+ case OP_PROP:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_RECURSE:
+ case OP_REF:
+ case OP_REFI:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SCOND:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_THEN_ARG:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
+ return SSB_FAIL;
+
+ /* We can ignore word boundary tests. */
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ tcode++;
+ break;
+
+ /* If we hit a bracket or a positive lookahead assertion, recurse to set
+ bits from within the subpattern. If it can't find anything, we have to
+ give up. If it finds some mandatory character(s), we are done for this
+ branch. Otherwise, carry on scanning after the subpattern. */
+
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_ASSERT:
+ rc = set_start_bits(tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+ if (rc == SSB_DONE) try_next = FALSE; else
+ {
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ }
+ break;
+
+ /* If we hit ALT or KET, it means we haven't found anything mandatory in
+ this branch, though we might have found something optional. For ALT, we
+ continue with the next alternative, but we have to arrange that the final
+ result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
+ return SSB_CONTINUE: if this is the top level, that indicates failure,
+ but after a nested subpattern, it causes scanning to continue. */
+
+ case OP_ALT:
+ yield = SSB_CONTINUE;
+ try_next = FALSE;
+ break;
+
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return SSB_CONTINUE;
+
+ /* Skip over callout */
+
+ case OP_CALLOUT:
+ tcode += 2 + 2*LINK_SIZE;
+ break;
+
+ /* Skip over lookbehind and negative lookahead assertions */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* BRAZERO does the bracket, but carries on. */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ rc = set_start_bits(++tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+/* =========================================================================
+ See the comment at the head of this function concerning the next line,
+ which was an old fudge for the benefit of OS/2.
+ dummy = 1;
+ ========================================================================= */
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* SKIPZERO skips the bracket. */
+
+ case OP_SKIPZERO:
+ tcode++;
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* Single-char * or ? sets the bit and tries the next item */
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
+ break;
+
+ /* Single-char upto sets the bit and tries the next */
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf);
+ break;
+
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf);
+ break;
+
+ /* At least one single char sets the bit and stops */
+
+ case OP_EXACT:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ try_next = FALSE;
+ break;
+
+ case OP_EXACTI:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
+ try_next = FALSE;
+ break;
+
+ /* Special spacing and line-terminating items. These recognize specific
+ lists of characters. The difference between VSPACE and ANYNL is that the
+ latter can match the two-character CRLF sequence, but that is not
+ relevant for finding the first character, so their code here is
+ identical. */
+
+ case OP_HSPACE:
+ SET_BIT(0x09);
+ SET_BIT(0x20);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0xA0);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ try_next = FALSE;
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(0x0A);
+ SET_BIT(0x0B);
+ SET_BIT(0x0C);
+ SET_BIT(0x0D);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+0085 */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0x85);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ try_next = FALSE;
+ break;
+
+ /* Single character types set the bits and stop. Note that if PCRE_UCP
+ is set, we do not see these op codes because \d etc are converted to
+ properties. Therefore, these apply in the case when only characters less
+ than 256 are recognized to match the types. */
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(start_bits, cbit_digit, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ ensure it is set as not whitespace. */
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] |= 0x08;
+ try_next = FALSE;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ not set it from the table. */
+
+ case OP_WHITESPACE:
+ c = start_bits[1]; /* Save in case it was already set */
+ set_type_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] = (start_bits[1] & ~0x08) | c;
+ try_next = FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(start_bits, cbit_word, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(start_bits, cbit_word, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ /* One or more character type fudges the pointer and restarts, knowing
+ it will hit a single character type and stop there. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ tcode++;
+ break;
+
+ case OP_TYPEEXACT:
+ tcode += 1 + IMM2_SIZE;
+ break;
+
+ /* Zero or more repeats of character types set the bits and then
+ try again. */
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ tcode += IMM2_SIZE; /* Fall through */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ switch(tcode[1])
+ {
+ default:
+ case OP_ANY:
+ case OP_ALLANY:
+ return SSB_FAIL;
+
+ case OP_HSPACE:
+ SET_BIT(0x09);
+ SET_BIT(0x20);
+#ifdef COMPILE_PCRE8
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0xA0);
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(0x0A);
+ SET_BIT(0x0B);
+ SET_BIT(0x0C);
+ SET_BIT(0x0D);
+#ifdef COMPILE_PCRE8
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+0085 */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0x85);
+ break;
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(start_bits, cbit_digit, table_limit, cd);
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ ensure it gets set as not whitespace. */
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] |= 0x08;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ avoid setting it. */
+
+ case OP_WHITESPACE:
+ c = start_bits[1]; /* Save in case it was already set */
+ set_type_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] = (start_bits[1] & ~0x08) | c;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(start_bits, cbit_word, table_limit, cd);
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(start_bits, cbit_word, table_limit, cd);
+ break;
+ }
+
+ tcode += 2;
+ break;
+
+ /* Character class where all the information is in a bit map: set the
+ bits and either carry on or not, according to the repeat count. If it was
+ a negative class, and we are operating with UTF-8 characters, any byte
+ with a value >= 0xc4 is a potentially valid starter because it starts a
+ character with a value > 255. */
+
+ case OP_NCLASS:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
+ {
+ start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
+ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
+ }
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ /* Fall through */
+
+ case OP_CLASS:
+ {
+ pcre_uint8 *map;
+ tcode++;
+ map = (pcre_uint8 *)tcode;
+
+ /* In UTF-8 mode, the bits in a bit map correspond to character
+ values, not to byte values. However, the bit map we are constructing is
+ for byte values. So we have to do a conversion for characters whose
+ value is > 127. In fact, there are only two possible starting bytes for
+ characters in the range 128 - 255. */
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
+ {
+ for (c = 0; c < 16; c++) start_bits[c] |= map[c];
+ for (c = 128; c < 256; c++)
+ {
+ if ((map[c/8] && (1 << (c&7))) != 0)
+ {
+ int d = (c >> 6) | 0xc0; /* Set bit for this starter */
+ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
+ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
+ }
+ }
+ }
+ else
+#endif
+ {
+ /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+ for (c = 0; c < 32; c++) start_bits[c] |= map[c];
+ }
+
+ /* Advance past the bit map, and act on what follows. For a zero
+ minimum repeat, continue; otherwise stop processing. */
+
+ tcode += 32 / sizeof(pcre_uchar);
+ switch (*tcode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ tcode++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
+ else try_next = FALSE;
+ break;
+
+ default:
+ try_next = FALSE;
+ break;
+ }
+ }
+ break; /* End of bitmap class handling */
+
+ } /* End of switch */
+ } /* End of try_next loop */
+
+ code += GET(code, 1); /* Advance to next branch */
+ }
+while (*code == OP_ALT);
+return yield;
+}
+
+
+
+
+
+/*************************************************
+* Study a compiled expression *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching. It returns a pcre[16]_extra block
+which then gets handed back to pcre_exec().
+
+Arguments:
+ re points to the compiled expression
+ options contains option bits
+ errorptr points to where to place error messages;
+ set NULL unless error
+
+Returns: pointer to a pcre[16]_extra block, with study_data filled in and
+ the appropriate flags set;
+ NULL on error or if no optimization possible
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
+pcre_study(const pcre *external_re, int options, const char **errorptr)
+#else
+PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
+pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
+#endif
+{
+int min;
+BOOL bits_set = FALSE;
+pcre_uint8 start_bits[32];
+PUBL(extra) *extra = NULL;
+pcre_study_data *study;
+const pcre_uint8 *tables;
+pcre_uchar *code;
+compile_data compile_block;
+const REAL_PCRE *re = (const REAL_PCRE *)external_re;
+
+*errorptr = NULL;
+
+if (re == NULL || re->magic_number != MAGIC_NUMBER)
+ {
+ *errorptr = "argument is not a compiled regular expression";
+ return NULL;
+ }
+
+if ((re->flags & PCRE_MODE) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ *errorptr = "argument is compiled in 16 bit mode";
+#else
+ *errorptr = "argument is compiled in 8 bit mode";
+#endif
+ return NULL;
+ }
+
+if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
+ {
+ *errorptr = "unknown or incorrect option bit(s) set";
+ return NULL;
+ }
+
+code = (pcre_uchar *)re + re->name_table_offset +
+ (re->name_count * re->name_entry_size);
+
+/* For an anchored pattern, or an unanchored pattern that has a first char, or
+a multiline pattern that matches only at "line starts", there is no point in
+seeking a list of starting bytes. */
+
+if ((re->options & PCRE_ANCHORED) == 0 &&
+ (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
+ {
+ int rc;
+
+ /* Set the character tables in the block that is passed around */
+
+ tables = re->tables;
+
+#ifdef COMPILE_PCRE8
+ if (tables == NULL)
+ (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+ (void *)(&tables));
+#else
+ if (tables == NULL)
+ (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+ (void *)(&tables));
+#endif
+
+ compile_block.lcc = tables + lcc_offset;
+ compile_block.fcc = tables + fcc_offset;
+ compile_block.cbits = tables + cbits_offset;
+ compile_block.ctypes = tables + ctypes_offset;
+
+ /* See if we can find a fixed set of initial characters for the pattern. */
+
+ memset(start_bits, 0, 32 * sizeof(pcre_uint8));
+ rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0,
+ &compile_block);
+ bits_set = rc == SSB_DONE;
+ if (rc == SSB_UNKNOWN)
+ {
+ *errorptr = "internal error: opcode not recognized";
+ return NULL;
+ }
+ }
+
+/* Find the minimum length of subject string. */
+
+switch(min = find_minlength(code, code, re->options, 0))
+ {
+ case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
+ case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
+ default: break;
+ }
+
+/* If a set of starting bytes has been identified, or if the minimum length is
+greater than zero, or if JIT optimization has been requested, get a
+pcre[16]_extra block and a pcre_study_data block. The study data is put in the
+latter, which is pointed to by the former, which may also get additional data
+set later by the calling program. At the moment, the size of pcre_study_data
+is fixed. We nevertheless save it in a field for returning via the
+pcre_fullinfo() function so that if it becomes variable in the future,
+we don't have to change that code. */
+
+if (bits_set || min > 0
+#ifdef SUPPORT_JIT
+ || (options & PCRE_STUDY_JIT_COMPILE) != 0
+#endif
+ )
+ {
+ extra = (PUBL(extra) *)(PUBL(malloc))
+ (sizeof(PUBL(extra)) + sizeof(pcre_study_data));
+ if (extra == NULL)
+ {
+ *errorptr = "failed to get memory";
+ return NULL;
+ }
+
+ study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra)));
+ extra->flags = PCRE_EXTRA_STUDY_DATA;
+ extra->study_data = study;
+
+ study->size = sizeof(pcre_study_data);
+ study->flags = 0;
+
+ /* Set the start bits always, to avoid unset memory errors if the
+ study data is written to a file, but set the flag only if any of the bits
+ are set, to save time looking when none are. */
+
+ if (bits_set)
+ {
+ study->flags |= PCRE_STUDY_MAPPED;
+ memcpy(study->start_bits, start_bits, sizeof(start_bits));
+ }
+ else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8));
+
+#ifdef PCRE_DEBUG
+ if (bits_set)
+ {
+ pcre_uint8 *ptr = start_bits;
+ int i;
+
+ printf("Start bits:\n");
+ for (i = 0; i < 32; i++)
+ printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n");
+ }
+#endif
+
+ /* Always set the minlength value in the block, because the JIT compiler
+ makes use of it. However, don't set the bit unless the length is greater than
+ zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time
+ checking the zero case. */
+
+ if (min > 0)
+ {
+ study->flags |= PCRE_STUDY_MINLEN;
+ study->minlength = min;
+ }
+ else study->minlength = 0;
+
+ /* If JIT support was compiled and requested, attempt the JIT compilation.
+ If no starting bytes were found, and the minimum length is zero, and JIT
+ compilation fails, abandon the extra block and return NULL. */
+
+#ifdef SUPPORT_JIT
+ extra->executable_jit = NULL;
+ if ((options & PCRE_STUDY_JIT_COMPILE) != 0) PRIV(jit_compile)(re, extra);
+ if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ pcre_free_study(extra);
+#endif
+#ifdef COMPILE_PCRE16
+ pcre16_free_study(extra);
+#endif
+ extra = NULL;
+ }
+#endif
+ }
+
+return extra;
+}
+
+
+/*************************************************
+* Free the study data *
+*************************************************/
+
+/* This function frees the memory that was obtained by pcre_study().
+
+Argument: a pointer to the pcre[16]_extra block
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void
+pcre_free_study(pcre_extra *extra)
+#else
+PCRE_EXP_DEFN void
+pcre16_free_study(pcre16_extra *extra)
+#endif
+{
+if (extra == NULL)
+ return;
+#ifdef SUPPORT_JIT
+if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ PRIV(jit_free)(extra->executable_jit);
+#endif
+PUBL(free)(extra);
+}
+
+/* End of pcre_study.c */
diff --git a/src/3rdparty/pcre/pcre_tables.c b/src/3rdparty/pcre/pcre_tables.c
new file mode 100644
index 0000000000..9e449f8888
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_tables.c
@@ -0,0 +1,568 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef PCRE_INCLUDED
+
+/* This module contains some fixed tables that are used by more than one of the
+PCRE code modules. The tables are also #included by the pcretest program, which
+uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
+clashes with the library. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#endif /* PCRE_INCLUDED */
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre_internal.h. */
+
+const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+* Tables for UTF-8 support *
+*************************************************/
+
+/* These are the breakpoints for different numbers of bytes in a UTF-8
+character. */
+
+#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
+ || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
+
+/* These tables are also required by pcretest in 16 bit mode. */
+
+const int PRIV(utf8_table1)[] =
+ { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+
+const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
+
+/* These are the indicator bits and the mask for the data bits to set in the
+first byte of a character, indexed by the number of additional bytes. */
+
+const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+/* Table of the number of extra bytes, indexed by the first byte masked with
+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
+
+const pcre_uint8 PRIV(utf8_table4)[] = {
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+
+#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
+
+#ifdef SUPPORT_UTF
+
+/* Table to translate from particular type value to the general value. */
+
+const int PRIV(ucp_gentype)[] = {
+ ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
+ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
+ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
+ ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
+ ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
+ ucp_P, ucp_P, /* Ps, Po */
+ ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
+ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
+};
+
+#ifdef SUPPORT_JIT
+/* This table reverses PRIV(ucp_gentype). We can save the cost
+of a memory load. */
+
+const int PRIV(ucp_typerange)[] = {
+ ucp_Cc, ucp_Cs,
+ ucp_Ll, ucp_Lu,
+ ucp_Mc, ucp_Mn,
+ ucp_Nd, ucp_No,
+ ucp_Pc, ucp_Ps,
+ ucp_Sc, ucp_So,
+ ucp_Zl, ucp_Zs,
+};
+#endif /* SUPPORT_JIT */
+
+/* The pcre_utt[] table below translates Unicode property names into type and
+code values. It is searched by binary chop, so must be in collating sequence of
+name. Originally, the table contained pointers to the name strings in the first
+field of each entry. However, that leads to a large number of relocations when
+a shared library is dynamically loaded. A significant reduction is made by
+putting all the names into a single, large string and then using offsets in the
+table itself. Maintenance is more error-prone, but frequent changes to this
+data are unlikely.
+
+July 2008: There is now a script called maint/GenerateUtt.py that can be used
+to generate this data automatically instead of maintaining it by hand.
+
+The script was updated in March 2009 to generate a new EBCDIC-compliant
+version. Like all other character and string literals that are compared against
+the regular expression pattern, we must use STR_ macros instead of literal
+strings to make sure that UTF-8 support works on EBCDIC platforms. */
+
+#define STRING_Any0 STR_A STR_n STR_y "\0"
+#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
+#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
+#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
+#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
+#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
+#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
+#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
+#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
+#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
+#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
+#define STRING_C0 STR_C "\0"
+#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
+#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
+#define STRING_Cc0 STR_C STR_c "\0"
+#define STRING_Cf0 STR_C STR_f "\0"
+#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
+#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
+#define STRING_Cn0 STR_C STR_n "\0"
+#define STRING_Co0 STR_C STR_o "\0"
+#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
+#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
+#define STRING_Cs0 STR_C STR_s "\0"
+#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
+#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
+#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
+#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
+#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
+#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
+#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
+#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
+#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
+#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
+#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
+#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
+#define STRING_Han0 STR_H STR_a STR_n "\0"
+#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
+#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
+#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
+#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
+#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
+#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
+#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
+#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
+#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
+#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
+#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
+#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
+#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
+#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
+#define STRING_L0 STR_L "\0"
+#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
+#define STRING_Lao0 STR_L STR_a STR_o "\0"
+#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
+#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
+#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
+#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
+#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
+#define STRING_Ll0 STR_L STR_l "\0"
+#define STRING_Lm0 STR_L STR_m "\0"
+#define STRING_Lo0 STR_L STR_o "\0"
+#define STRING_Lt0 STR_L STR_t "\0"
+#define STRING_Lu0 STR_L STR_u "\0"
+#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
+#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
+#define STRING_M0 STR_M "\0"
+#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
+#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
+#define STRING_Mc0 STR_M STR_c "\0"
+#define STRING_Me0 STR_M STR_e "\0"
+#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
+#define STRING_Mn0 STR_M STR_n "\0"
+#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
+#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
+#define STRING_N0 STR_N "\0"
+#define STRING_Nd0 STR_N STR_d "\0"
+#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
+#define STRING_Nko0 STR_N STR_k STR_o "\0"
+#define STRING_Nl0 STR_N STR_l "\0"
+#define STRING_No0 STR_N STR_o "\0"
+#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
+#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
+#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
+#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
+#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
+#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
+#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
+#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
+#define STRING_P0 STR_P "\0"
+#define STRING_Pc0 STR_P STR_c "\0"
+#define STRING_Pd0 STR_P STR_d "\0"
+#define STRING_Pe0 STR_P STR_e "\0"
+#define STRING_Pf0 STR_P STR_f "\0"
+#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
+#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
+#define STRING_Pi0 STR_P STR_i "\0"
+#define STRING_Po0 STR_P STR_o "\0"
+#define STRING_Ps0 STR_P STR_s "\0"
+#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
+#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
+#define STRING_S0 STR_S "\0"
+#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
+#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
+#define STRING_Sc0 STR_S STR_c "\0"
+#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
+#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
+#define STRING_Sk0 STR_S STR_k "\0"
+#define STRING_Sm0 STR_S STR_m "\0"
+#define STRING_So0 STR_S STR_o "\0"
+#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
+#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
+#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
+#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
+#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
+#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
+#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
+#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
+#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
+#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
+#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
+#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
+#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
+#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
+#define STRING_Vai0 STR_V STR_a STR_i "\0"
+#define STRING_Xan0 STR_X STR_a STR_n "\0"
+#define STRING_Xps0 STR_X STR_p STR_s "\0"
+#define STRING_Xsp0 STR_X STR_s STR_p "\0"
+#define STRING_Xwd0 STR_X STR_w STR_d "\0"
+#define STRING_Yi0 STR_Y STR_i "\0"
+#define STRING_Z0 STR_Z "\0"
+#define STRING_Zl0 STR_Z STR_l "\0"
+#define STRING_Zp0 STR_Z STR_p "\0"
+#define STRING_Zs0 STR_Z STR_s "\0"
+
+const char PRIV(utt_names)[] =
+ STRING_Any0
+ STRING_Arabic0
+ STRING_Armenian0
+ STRING_Avestan0
+ STRING_Balinese0
+ STRING_Bamum0
+ STRING_Batak0
+ STRING_Bengali0
+ STRING_Bopomofo0
+ STRING_Brahmi0
+ STRING_Braille0
+ STRING_Buginese0
+ STRING_Buhid0
+ STRING_C0
+ STRING_Canadian_Aboriginal0
+ STRING_Carian0
+ STRING_Cc0
+ STRING_Cf0
+ STRING_Cham0
+ STRING_Cherokee0
+ STRING_Cn0
+ STRING_Co0
+ STRING_Common0
+ STRING_Coptic0
+ STRING_Cs0
+ STRING_Cuneiform0
+ STRING_Cypriot0
+ STRING_Cyrillic0
+ STRING_Deseret0
+ STRING_Devanagari0
+ STRING_Egyptian_Hieroglyphs0
+ STRING_Ethiopic0
+ STRING_Georgian0
+ STRING_Glagolitic0
+ STRING_Gothic0
+ STRING_Greek0
+ STRING_Gujarati0
+ STRING_Gurmukhi0
+ STRING_Han0
+ STRING_Hangul0
+ STRING_Hanunoo0
+ STRING_Hebrew0
+ STRING_Hiragana0
+ STRING_Imperial_Aramaic0
+ STRING_Inherited0
+ STRING_Inscriptional_Pahlavi0
+ STRING_Inscriptional_Parthian0
+ STRING_Javanese0
+ STRING_Kaithi0
+ STRING_Kannada0
+ STRING_Katakana0
+ STRING_Kayah_Li0
+ STRING_Kharoshthi0
+ STRING_Khmer0
+ STRING_L0
+ STRING_L_AMPERSAND0
+ STRING_Lao0
+ STRING_Latin0
+ STRING_Lepcha0
+ STRING_Limbu0
+ STRING_Linear_B0
+ STRING_Lisu0
+ STRING_Ll0
+ STRING_Lm0
+ STRING_Lo0
+ STRING_Lt0
+ STRING_Lu0
+ STRING_Lycian0
+ STRING_Lydian0
+ STRING_M0
+ STRING_Malayalam0
+ STRING_Mandaic0
+ STRING_Mc0
+ STRING_Me0
+ STRING_Meetei_Mayek0
+ STRING_Mn0
+ STRING_Mongolian0
+ STRING_Myanmar0
+ STRING_N0
+ STRING_Nd0
+ STRING_New_Tai_Lue0
+ STRING_Nko0
+ STRING_Nl0
+ STRING_No0
+ STRING_Ogham0
+ STRING_Ol_Chiki0
+ STRING_Old_Italic0
+ STRING_Old_Persian0
+ STRING_Old_South_Arabian0
+ STRING_Old_Turkic0
+ STRING_Oriya0
+ STRING_Osmanya0
+ STRING_P0
+ STRING_Pc0
+ STRING_Pd0
+ STRING_Pe0
+ STRING_Pf0
+ STRING_Phags_Pa0
+ STRING_Phoenician0
+ STRING_Pi0
+ STRING_Po0
+ STRING_Ps0
+ STRING_Rejang0
+ STRING_Runic0
+ STRING_S0
+ STRING_Samaritan0
+ STRING_Saurashtra0
+ STRING_Sc0
+ STRING_Shavian0
+ STRING_Sinhala0
+ STRING_Sk0
+ STRING_Sm0
+ STRING_So0
+ STRING_Sundanese0
+ STRING_Syloti_Nagri0
+ STRING_Syriac0
+ STRING_Tagalog0
+ STRING_Tagbanwa0
+ STRING_Tai_Le0
+ STRING_Tai_Tham0
+ STRING_Tai_Viet0
+ STRING_Tamil0
+ STRING_Telugu0
+ STRING_Thaana0
+ STRING_Thai0
+ STRING_Tibetan0
+ STRING_Tifinagh0
+ STRING_Ugaritic0
+ STRING_Vai0
+ STRING_Xan0
+ STRING_Xps0
+ STRING_Xsp0
+ STRING_Xwd0
+ STRING_Yi0
+ STRING_Z0
+ STRING_Zl0
+ STRING_Zp0
+ STRING_Zs0;
+
+const ucp_type_table PRIV(utt)[] = {
+ { 0, PT_ANY, 0 },
+ { 4, PT_SC, ucp_Arabic },
+ { 11, PT_SC, ucp_Armenian },
+ { 20, PT_SC, ucp_Avestan },
+ { 28, PT_SC, ucp_Balinese },
+ { 37, PT_SC, ucp_Bamum },
+ { 43, PT_SC, ucp_Batak },
+ { 49, PT_SC, ucp_Bengali },
+ { 57, PT_SC, ucp_Bopomofo },
+ { 66, PT_SC, ucp_Brahmi },
+ { 73, PT_SC, ucp_Braille },
+ { 81, PT_SC, ucp_Buginese },
+ { 90, PT_SC, ucp_Buhid },
+ { 96, PT_GC, ucp_C },
+ { 98, PT_SC, ucp_Canadian_Aboriginal },
+ { 118, PT_SC, ucp_Carian },
+ { 125, PT_PC, ucp_Cc },
+ { 128, PT_PC, ucp_Cf },
+ { 131, PT_SC, ucp_Cham },
+ { 136, PT_SC, ucp_Cherokee },
+ { 145, PT_PC, ucp_Cn },
+ { 148, PT_PC, ucp_Co },
+ { 151, PT_SC, ucp_Common },
+ { 158, PT_SC, ucp_Coptic },
+ { 165, PT_PC, ucp_Cs },
+ { 168, PT_SC, ucp_Cuneiform },
+ { 178, PT_SC, ucp_Cypriot },
+ { 186, PT_SC, ucp_Cyrillic },
+ { 195, PT_SC, ucp_Deseret },
+ { 203, PT_SC, ucp_Devanagari },
+ { 214, PT_SC, ucp_Egyptian_Hieroglyphs },
+ { 235, PT_SC, ucp_Ethiopic },
+ { 244, PT_SC, ucp_Georgian },
+ { 253, PT_SC, ucp_Glagolitic },
+ { 264, PT_SC, ucp_Gothic },
+ { 271, PT_SC, ucp_Greek },
+ { 277, PT_SC, ucp_Gujarati },
+ { 286, PT_SC, ucp_Gurmukhi },
+ { 295, PT_SC, ucp_Han },
+ { 299, PT_SC, ucp_Hangul },
+ { 306, PT_SC, ucp_Hanunoo },
+ { 314, PT_SC, ucp_Hebrew },
+ { 321, PT_SC, ucp_Hiragana },
+ { 330, PT_SC, ucp_Imperial_Aramaic },
+ { 347, PT_SC, ucp_Inherited },
+ { 357, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 379, PT_SC, ucp_Inscriptional_Parthian },
+ { 402, PT_SC, ucp_Javanese },
+ { 411, PT_SC, ucp_Kaithi },
+ { 418, PT_SC, ucp_Kannada },
+ { 426, PT_SC, ucp_Katakana },
+ { 435, PT_SC, ucp_Kayah_Li },
+ { 444, PT_SC, ucp_Kharoshthi },
+ { 455, PT_SC, ucp_Khmer },
+ { 461, PT_GC, ucp_L },
+ { 463, PT_LAMP, 0 },
+ { 466, PT_SC, ucp_Lao },
+ { 470, PT_SC, ucp_Latin },
+ { 476, PT_SC, ucp_Lepcha },
+ { 483, PT_SC, ucp_Limbu },
+ { 489, PT_SC, ucp_Linear_B },
+ { 498, PT_SC, ucp_Lisu },
+ { 503, PT_PC, ucp_Ll },
+ { 506, PT_PC, ucp_Lm },
+ { 509, PT_PC, ucp_Lo },
+ { 512, PT_PC, ucp_Lt },
+ { 515, PT_PC, ucp_Lu },
+ { 518, PT_SC, ucp_Lycian },
+ { 525, PT_SC, ucp_Lydian },
+ { 532, PT_GC, ucp_M },
+ { 534, PT_SC, ucp_Malayalam },
+ { 544, PT_SC, ucp_Mandaic },
+ { 552, PT_PC, ucp_Mc },
+ { 555, PT_PC, ucp_Me },
+ { 558, PT_SC, ucp_Meetei_Mayek },
+ { 571, PT_PC, ucp_Mn },
+ { 574, PT_SC, ucp_Mongolian },
+ { 584, PT_SC, ucp_Myanmar },
+ { 592, PT_GC, ucp_N },
+ { 594, PT_PC, ucp_Nd },
+ { 597, PT_SC, ucp_New_Tai_Lue },
+ { 609, PT_SC, ucp_Nko },
+ { 613, PT_PC, ucp_Nl },
+ { 616, PT_PC, ucp_No },
+ { 619, PT_SC, ucp_Ogham },
+ { 625, PT_SC, ucp_Ol_Chiki },
+ { 634, PT_SC, ucp_Old_Italic },
+ { 645, PT_SC, ucp_Old_Persian },
+ { 657, PT_SC, ucp_Old_South_Arabian },
+ { 675, PT_SC, ucp_Old_Turkic },
+ { 686, PT_SC, ucp_Oriya },
+ { 692, PT_SC, ucp_Osmanya },
+ { 700, PT_GC, ucp_P },
+ { 702, PT_PC, ucp_Pc },
+ { 705, PT_PC, ucp_Pd },
+ { 708, PT_PC, ucp_Pe },
+ { 711, PT_PC, ucp_Pf },
+ { 714, PT_SC, ucp_Phags_Pa },
+ { 723, PT_SC, ucp_Phoenician },
+ { 734, PT_PC, ucp_Pi },
+ { 737, PT_PC, ucp_Po },
+ { 740, PT_PC, ucp_Ps },
+ { 743, PT_SC, ucp_Rejang },
+ { 750, PT_SC, ucp_Runic },
+ { 756, PT_GC, ucp_S },
+ { 758, PT_SC, ucp_Samaritan },
+ { 768, PT_SC, ucp_Saurashtra },
+ { 779, PT_PC, ucp_Sc },
+ { 782, PT_SC, ucp_Shavian },
+ { 790, PT_SC, ucp_Sinhala },
+ { 798, PT_PC, ucp_Sk },
+ { 801, PT_PC, ucp_Sm },
+ { 804, PT_PC, ucp_So },
+ { 807, PT_SC, ucp_Sundanese },
+ { 817, PT_SC, ucp_Syloti_Nagri },
+ { 830, PT_SC, ucp_Syriac },
+ { 837, PT_SC, ucp_Tagalog },
+ { 845, PT_SC, ucp_Tagbanwa },
+ { 854, PT_SC, ucp_Tai_Le },
+ { 861, PT_SC, ucp_Tai_Tham },
+ { 870, PT_SC, ucp_Tai_Viet },
+ { 879, PT_SC, ucp_Tamil },
+ { 885, PT_SC, ucp_Telugu },
+ { 892, PT_SC, ucp_Thaana },
+ { 899, PT_SC, ucp_Thai },
+ { 904, PT_SC, ucp_Tibetan },
+ { 912, PT_SC, ucp_Tifinagh },
+ { 921, PT_SC, ucp_Ugaritic },
+ { 930, PT_SC, ucp_Vai },
+ { 934, PT_ALNUM, 0 },
+ { 938, PT_PXSPACE, 0 },
+ { 942, PT_SPACE, 0 },
+ { 946, PT_WORD, 0 },
+ { 950, PT_SC, ucp_Yi },
+ { 953, PT_GC, ucp_Z },
+ { 955, PT_PC, ucp_Zl },
+ { 958, PT_PC, ucp_Zp },
+ { 961, PT_PC, ucp_Zs }
+};
+
+const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
+
+#endif /* SUPPORT_UTF */
+
+/* End of pcre_tables.c */
diff --git a/src/3rdparty/pcre/pcre_ucd.c b/src/3rdparty/pcre/pcre_ucd.c
new file mode 100644
index 0000000000..48fa486635
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_ucd.c
@@ -0,0 +1,2981 @@
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+/* Unicode character database. */
+/* This file was autogenerated by the MultiStage2.py script. */
+/* Total size: 60384 bytes, block size: 128. */
+
+/* The tables herein are needed only when UCP support is built */
+/* into PCRE. This module should not be referenced otherwise, so */
+/* it should not matter whether it is compiled or not. However */
+/* a comment was received about space saving - maybe the guy linked */
+/* all the modules rather than using a library - so we include a */
+/* condition to cut out the tables when not needed. But don't leave */
+/* a totally empty module because some compilers barf at that. */
+/* Instead, just supply small dummy tables. */
+
+#ifndef SUPPORT_UCP
+const ucd_record PRIV(ucd_records)[] = {{0,0,0 }};
+const pcre_uint8 PRIV(ucd_stage1)[] = {0};
+const pcre_uint16 PRIV(ucd_stage2)[] = {0};
+#else
+
+/* When recompiling tables with a new Unicode version,
+please check types in the structure definition from pcre_internal.h:
+typedef struct {
+pcre_uint8 property_0;
+pcre_uint8 property_1;
+pcre_int32 property_2;
+} ucd_record; */
+
+
+const ucd_record PRIV(ucd_records)[] = { /* 4320 bytes, record size 8 */
+ { 9, 0, 0, }, /* 0 */
+ { 9, 29, 0, }, /* 1 */
+ { 9, 21, 0, }, /* 2 */
+ { 9, 23, 0, }, /* 3 */
+ { 9, 22, 0, }, /* 4 */
+ { 9, 18, 0, }, /* 5 */
+ { 9, 25, 0, }, /* 6 */
+ { 9, 17, 0, }, /* 7 */
+ { 9, 13, 0, }, /* 8 */
+ { 33, 9, 32, }, /* 9 */
+ { 9, 24, 0, }, /* 10 */
+ { 9, 16, 0, }, /* 11 */
+ { 33, 5, -32, }, /* 12 */
+ { 9, 26, 0, }, /* 13 */
+ { 33, 5, 0, }, /* 14 */
+ { 9, 20, 0, }, /* 15 */
+ { 9, 1, 0, }, /* 16 */
+ { 9, 15, 0, }, /* 17 */
+ { 9, 5, 743, }, /* 18 */
+ { 9, 19, 0, }, /* 19 */
+ { 33, 5, 121, }, /* 20 */
+ { 33, 9, 1, }, /* 21 */
+ { 33, 5, -1, }, /* 22 */
+ { 33, 9, -199, }, /* 23 */
+ { 33, 5, -232, }, /* 24 */
+ { 33, 9, -121, }, /* 25 */
+ { 33, 5, -300, }, /* 26 */
+ { 33, 5, 195, }, /* 27 */
+ { 33, 9, 210, }, /* 28 */
+ { 33, 9, 206, }, /* 29 */
+ { 33, 9, 205, }, /* 30 */
+ { 33, 9, 79, }, /* 31 */
+ { 33, 9, 202, }, /* 32 */
+ { 33, 9, 203, }, /* 33 */
+ { 33, 9, 207, }, /* 34 */
+ { 33, 5, 97, }, /* 35 */
+ { 33, 9, 211, }, /* 36 */
+ { 33, 9, 209, }, /* 37 */
+ { 33, 5, 163, }, /* 38 */
+ { 33, 9, 213, }, /* 39 */
+ { 33, 5, 130, }, /* 40 */
+ { 33, 9, 214, }, /* 41 */
+ { 33, 9, 218, }, /* 42 */
+ { 33, 9, 217, }, /* 43 */
+ { 33, 9, 219, }, /* 44 */
+ { 33, 7, 0, }, /* 45 */
+ { 33, 5, 56, }, /* 46 */
+ { 33, 9, 2, }, /* 47 */
+ { 33, 8, -1, }, /* 48 */
+ { 33, 5, -2, }, /* 49 */
+ { 33, 5, -79, }, /* 50 */
+ { 33, 9, -97, }, /* 51 */
+ { 33, 9, -56, }, /* 52 */
+ { 33, 9, -130, }, /* 53 */
+ { 33, 9, 10795, }, /* 54 */
+ { 33, 9, -163, }, /* 55 */
+ { 33, 9, 10792, }, /* 56 */
+ { 33, 5, 10815, }, /* 57 */
+ { 33, 9, -195, }, /* 58 */
+ { 33, 9, 69, }, /* 59 */
+ { 33, 9, 71, }, /* 60 */
+ { 33, 5, 10783, }, /* 61 */
+ { 33, 5, 10780, }, /* 62 */
+ { 33, 5, 10782, }, /* 63 */
+ { 33, 5, -210, }, /* 64 */
+ { 33, 5, -206, }, /* 65 */
+ { 33, 5, -205, }, /* 66 */
+ { 33, 5, -202, }, /* 67 */
+ { 33, 5, -203, }, /* 68 */
+ { 33, 5, -207, }, /* 69 */
+ { 33, 5, 42280, }, /* 70 */
+ { 33, 5, -209, }, /* 71 */
+ { 33, 5, -211, }, /* 72 */
+ { 33, 5, 10743, }, /* 73 */
+ { 33, 5, 10749, }, /* 74 */
+ { 33, 5, -213, }, /* 75 */
+ { 33, 5, -214, }, /* 76 */
+ { 33, 5, 10727, }, /* 77 */
+ { 33, 5, -218, }, /* 78 */
+ { 33, 5, -69, }, /* 79 */
+ { 33, 5, -217, }, /* 80 */
+ { 33, 5, -71, }, /* 81 */
+ { 33, 5, -219, }, /* 82 */
+ { 33, 6, 0, }, /* 83 */
+ { 9, 6, 0, }, /* 84 */
+ { 3, 24, 0, }, /* 85 */
+ { 27, 12, 0, }, /* 86 */
+ { 27, 12, 84, }, /* 87 */
+ { 19, 9, 1, }, /* 88 */
+ { 19, 5, -1, }, /* 89 */
+ { 19, 24, 0, }, /* 90 */
+ { 9, 2, 0, }, /* 91 */
+ { 19, 6, 0, }, /* 92 */
+ { 19, 5, 130, }, /* 93 */
+ { 19, 9, 38, }, /* 94 */
+ { 19, 9, 37, }, /* 95 */
+ { 19, 9, 64, }, /* 96 */
+ { 19, 9, 63, }, /* 97 */
+ { 19, 5, 0, }, /* 98 */
+ { 19, 9, 32, }, /* 99 */
+ { 19, 5, -38, }, /* 100 */
+ { 19, 5, -37, }, /* 101 */
+ { 19, 5, -32, }, /* 102 */
+ { 19, 5, -31, }, /* 103 */
+ { 19, 5, -64, }, /* 104 */
+ { 19, 5, -63, }, /* 105 */
+ { 19, 9, 8, }, /* 106 */
+ { 19, 5, -62, }, /* 107 */
+ { 19, 5, -57, }, /* 108 */
+ { 19, 9, 0, }, /* 109 */
+ { 19, 5, -47, }, /* 110 */
+ { 19, 5, -54, }, /* 111 */
+ { 19, 5, -8, }, /* 112 */
+ { 10, 9, 1, }, /* 113 */
+ { 10, 5, -1, }, /* 114 */
+ { 19, 5, -86, }, /* 115 */
+ { 19, 5, -80, }, /* 116 */
+ { 19, 5, 7, }, /* 117 */
+ { 19, 9, -60, }, /* 118 */
+ { 19, 5, -96, }, /* 119 */
+ { 19, 25, 0, }, /* 120 */
+ { 19, 9, -7, }, /* 121 */
+ { 19, 9, -130, }, /* 122 */
+ { 12, 9, 80, }, /* 123 */
+ { 12, 9, 32, }, /* 124 */
+ { 12, 5, -32, }, /* 125 */
+ { 12, 5, -80, }, /* 126 */
+ { 12, 9, 1, }, /* 127 */
+ { 12, 5, -1, }, /* 128 */
+ { 12, 26, 0, }, /* 129 */
+ { 12, 12, 0, }, /* 130 */
+ { 12, 11, 0, }, /* 131 */
+ { 12, 9, 15, }, /* 132 */
+ { 12, 5, -15, }, /* 133 */
+ { 1, 9, 48, }, /* 134 */
+ { 1, 6, 0, }, /* 135 */
+ { 1, 21, 0, }, /* 136 */
+ { 1, 5, -48, }, /* 137 */
+ { 1, 5, 0, }, /* 138 */
+ { 1, 17, 0, }, /* 139 */
+ { 25, 12, 0, }, /* 140 */
+ { 25, 17, 0, }, /* 141 */
+ { 25, 21, 0, }, /* 142 */
+ { 25, 7, 0, }, /* 143 */
+ { 0, 1, 0, }, /* 144 */
+ { 0, 25, 0, }, /* 145 */
+ { 0, 21, 0, }, /* 146 */
+ { 0, 23, 0, }, /* 147 */
+ { 0, 26, 0, }, /* 148 */
+ { 0, 12, 0, }, /* 149 */
+ { 0, 7, 0, }, /* 150 */
+ { 0, 6, 0, }, /* 151 */
+ { 0, 13, 0, }, /* 152 */
+ { 49, 21, 0, }, /* 153 */
+ { 49, 1, 0, }, /* 154 */
+ { 49, 7, 0, }, /* 155 */
+ { 49, 12, 0, }, /* 156 */
+ { 55, 7, 0, }, /* 157 */
+ { 55, 12, 0, }, /* 158 */
+ { 63, 13, 0, }, /* 159 */
+ { 63, 7, 0, }, /* 160 */
+ { 63, 12, 0, }, /* 161 */
+ { 63, 6, 0, }, /* 162 */
+ { 63, 26, 0, }, /* 163 */
+ { 63, 21, 0, }, /* 164 */
+ { 89, 7, 0, }, /* 165 */
+ { 89, 12, 0, }, /* 166 */
+ { 89, 6, 0, }, /* 167 */
+ { 89, 21, 0, }, /* 168 */
+ { 94, 7, 0, }, /* 169 */
+ { 94, 12, 0, }, /* 170 */
+ { 94, 21, 0, }, /* 171 */
+ { 14, 12, 0, }, /* 172 */
+ { 14, 10, 0, }, /* 173 */
+ { 14, 7, 0, }, /* 174 */
+ { 14, 13, 0, }, /* 175 */
+ { 14, 6, 0, }, /* 176 */
+ { 2, 12, 0, }, /* 177 */
+ { 2, 10, 0, }, /* 178 */
+ { 2, 7, 0, }, /* 179 */
+ { 2, 13, 0, }, /* 180 */
+ { 2, 23, 0, }, /* 181 */
+ { 2, 15, 0, }, /* 182 */
+ { 2, 26, 0, }, /* 183 */
+ { 21, 12, 0, }, /* 184 */
+ { 21, 10, 0, }, /* 185 */
+ { 21, 7, 0, }, /* 186 */
+ { 21, 13, 0, }, /* 187 */
+ { 20, 12, 0, }, /* 188 */
+ { 20, 10, 0, }, /* 189 */
+ { 20, 7, 0, }, /* 190 */
+ { 20, 13, 0, }, /* 191 */
+ { 20, 23, 0, }, /* 192 */
+ { 43, 12, 0, }, /* 193 */
+ { 43, 10, 0, }, /* 194 */
+ { 43, 7, 0, }, /* 195 */
+ { 43, 13, 0, }, /* 196 */
+ { 43, 26, 0, }, /* 197 */
+ { 43, 15, 0, }, /* 198 */
+ { 53, 12, 0, }, /* 199 */
+ { 53, 7, 0, }, /* 200 */
+ { 53, 10, 0, }, /* 201 */
+ { 53, 13, 0, }, /* 202 */
+ { 53, 15, 0, }, /* 203 */
+ { 53, 26, 0, }, /* 204 */
+ { 53, 23, 0, }, /* 205 */
+ { 54, 10, 0, }, /* 206 */
+ { 54, 7, 0, }, /* 207 */
+ { 54, 12, 0, }, /* 208 */
+ { 54, 13, 0, }, /* 209 */
+ { 54, 15, 0, }, /* 210 */
+ { 54, 26, 0, }, /* 211 */
+ { 28, 10, 0, }, /* 212 */
+ { 28, 7, 0, }, /* 213 */
+ { 28, 12, 0, }, /* 214 */
+ { 28, 13, 0, }, /* 215 */
+ { 36, 10, 0, }, /* 216 */
+ { 36, 7, 0, }, /* 217 */
+ { 36, 12, 0, }, /* 218 */
+ { 36, 13, 0, }, /* 219 */
+ { 36, 15, 0, }, /* 220 */
+ { 36, 26, 0, }, /* 221 */
+ { 47, 10, 0, }, /* 222 */
+ { 47, 7, 0, }, /* 223 */
+ { 47, 12, 0, }, /* 224 */
+ { 47, 21, 0, }, /* 225 */
+ { 56, 7, 0, }, /* 226 */
+ { 56, 12, 0, }, /* 227 */
+ { 56, 6, 0, }, /* 228 */
+ { 56, 21, 0, }, /* 229 */
+ { 56, 13, 0, }, /* 230 */
+ { 32, 7, 0, }, /* 231 */
+ { 32, 12, 0, }, /* 232 */
+ { 32, 6, 0, }, /* 233 */
+ { 32, 13, 0, }, /* 234 */
+ { 57, 7, 0, }, /* 235 */
+ { 57, 26, 0, }, /* 236 */
+ { 57, 21, 0, }, /* 237 */
+ { 57, 12, 0, }, /* 238 */
+ { 57, 13, 0, }, /* 239 */
+ { 57, 15, 0, }, /* 240 */
+ { 57, 22, 0, }, /* 241 */
+ { 57, 18, 0, }, /* 242 */
+ { 57, 10, 0, }, /* 243 */
+ { 38, 7, 0, }, /* 244 */
+ { 38, 10, 0, }, /* 245 */
+ { 38, 12, 0, }, /* 246 */
+ { 38, 13, 0, }, /* 247 */
+ { 38, 21, 0, }, /* 248 */
+ { 38, 26, 0, }, /* 249 */
+ { 16, 9, 7264, }, /* 250 */
+ { 16, 7, 0, }, /* 251 */
+ { 16, 6, 0, }, /* 252 */
+ { 23, 7, 0, }, /* 253 */
+ { 15, 7, 0, }, /* 254 */
+ { 15, 12, 0, }, /* 255 */
+ { 15, 26, 0, }, /* 256 */
+ { 15, 21, 0, }, /* 257 */
+ { 15, 15, 0, }, /* 258 */
+ { 8, 7, 0, }, /* 259 */
+ { 7, 17, 0, }, /* 260 */
+ { 7, 7, 0, }, /* 261 */
+ { 7, 21, 0, }, /* 262 */
+ { 40, 29, 0, }, /* 263 */
+ { 40, 7, 0, }, /* 264 */
+ { 40, 22, 0, }, /* 265 */
+ { 40, 18, 0, }, /* 266 */
+ { 45, 7, 0, }, /* 267 */
+ { 45, 14, 0, }, /* 268 */
+ { 50, 7, 0, }, /* 269 */
+ { 50, 12, 0, }, /* 270 */
+ { 24, 7, 0, }, /* 271 */
+ { 24, 12, 0, }, /* 272 */
+ { 6, 7, 0, }, /* 273 */
+ { 6, 12, 0, }, /* 274 */
+ { 51, 7, 0, }, /* 275 */
+ { 51, 12, 0, }, /* 276 */
+ { 31, 7, 0, }, /* 277 */
+ { 31, 1, 0, }, /* 278 */
+ { 31, 10, 0, }, /* 279 */
+ { 31, 12, 0, }, /* 280 */
+ { 31, 21, 0, }, /* 281 */
+ { 31, 6, 0, }, /* 282 */
+ { 31, 23, 0, }, /* 283 */
+ { 31, 13, 0, }, /* 284 */
+ { 31, 15, 0, }, /* 285 */
+ { 37, 21, 0, }, /* 286 */
+ { 37, 17, 0, }, /* 287 */
+ { 37, 12, 0, }, /* 288 */
+ { 37, 29, 0, }, /* 289 */
+ { 37, 13, 0, }, /* 290 */
+ { 37, 7, 0, }, /* 291 */
+ { 37, 6, 0, }, /* 292 */
+ { 34, 7, 0, }, /* 293 */
+ { 34, 12, 0, }, /* 294 */
+ { 34, 10, 0, }, /* 295 */
+ { 34, 26, 0, }, /* 296 */
+ { 34, 21, 0, }, /* 297 */
+ { 34, 13, 0, }, /* 298 */
+ { 52, 7, 0, }, /* 299 */
+ { 39, 7, 0, }, /* 300 */
+ { 39, 10, 0, }, /* 301 */
+ { 39, 13, 0, }, /* 302 */
+ { 39, 15, 0, }, /* 303 */
+ { 39, 26, 0, }, /* 304 */
+ { 31, 26, 0, }, /* 305 */
+ { 5, 7, 0, }, /* 306 */
+ { 5, 12, 0, }, /* 307 */
+ { 5, 10, 0, }, /* 308 */
+ { 5, 21, 0, }, /* 309 */
+ { 90, 7, 0, }, /* 310 */
+ { 90, 10, 0, }, /* 311 */
+ { 90, 12, 0, }, /* 312 */
+ { 90, 13, 0, }, /* 313 */
+ { 90, 21, 0, }, /* 314 */
+ { 90, 6, 0, }, /* 315 */
+ { 61, 12, 0, }, /* 316 */
+ { 61, 10, 0, }, /* 317 */
+ { 61, 7, 0, }, /* 318 */
+ { 61, 13, 0, }, /* 319 */
+ { 61, 21, 0, }, /* 320 */
+ { 61, 26, 0, }, /* 321 */
+ { 75, 12, 0, }, /* 322 */
+ { 75, 10, 0, }, /* 323 */
+ { 75, 7, 0, }, /* 324 */
+ { 75, 13, 0, }, /* 325 */
+ { 92, 7, 0, }, /* 326 */
+ { 92, 12, 0, }, /* 327 */
+ { 92, 10, 0, }, /* 328 */
+ { 92, 21, 0, }, /* 329 */
+ { 69, 7, 0, }, /* 330 */
+ { 69, 10, 0, }, /* 331 */
+ { 69, 12, 0, }, /* 332 */
+ { 69, 21, 0, }, /* 333 */
+ { 69, 13, 0, }, /* 334 */
+ { 72, 13, 0, }, /* 335 */
+ { 72, 7, 0, }, /* 336 */
+ { 72, 6, 0, }, /* 337 */
+ { 72, 21, 0, }, /* 338 */
+ { 9, 10, 0, }, /* 339 */
+ { 9, 7, 0, }, /* 340 */
+ { 12, 5, 0, }, /* 341 */
+ { 12, 6, 0, }, /* 342 */
+ { 33, 5, 35332, }, /* 343 */
+ { 33, 5, 3814, }, /* 344 */
+ { 33, 5, -59, }, /* 345 */
+ { 33, 9, -7615, }, /* 346 */
+ { 19, 5, 8, }, /* 347 */
+ { 19, 9, -8, }, /* 348 */
+ { 19, 5, 74, }, /* 349 */
+ { 19, 5, 86, }, /* 350 */
+ { 19, 5, 100, }, /* 351 */
+ { 19, 5, 128, }, /* 352 */
+ { 19, 5, 112, }, /* 353 */
+ { 19, 5, 126, }, /* 354 */
+ { 19, 8, -8, }, /* 355 */
+ { 19, 5, 9, }, /* 356 */
+ { 19, 9, -74, }, /* 357 */
+ { 19, 8, -9, }, /* 358 */
+ { 19, 5, -7205, }, /* 359 */
+ { 19, 9, -86, }, /* 360 */
+ { 19, 9, -100, }, /* 361 */
+ { 19, 9, -112, }, /* 362 */
+ { 19, 9, -128, }, /* 363 */
+ { 19, 9, -126, }, /* 364 */
+ { 27, 1, 0, }, /* 365 */
+ { 9, 27, 0, }, /* 366 */
+ { 9, 28, 0, }, /* 367 */
+ { 27, 11, 0, }, /* 368 */
+ { 9, 9, 0, }, /* 369 */
+ { 9, 5, 0, }, /* 370 */
+ { 19, 9, -7517, }, /* 371 */
+ { 33, 9, -8383, }, /* 372 */
+ { 33, 9, -8262, }, /* 373 */
+ { 33, 9, 28, }, /* 374 */
+ { 33, 5, -28, }, /* 375 */
+ { 33, 14, 16, }, /* 376 */
+ { 33, 14, -16, }, /* 377 */
+ { 33, 14, 0, }, /* 378 */
+ { 9, 26, 26, }, /* 379 */
+ { 9, 26, -26, }, /* 380 */
+ { 4, 26, 0, }, /* 381 */
+ { 17, 9, 48, }, /* 382 */
+ { 17, 5, -48, }, /* 383 */
+ { 33, 9, -10743, }, /* 384 */
+ { 33, 9, -3814, }, /* 385 */
+ { 33, 9, -10727, }, /* 386 */
+ { 33, 5, -10795, }, /* 387 */
+ { 33, 5, -10792, }, /* 388 */
+ { 33, 9, -10780, }, /* 389 */
+ { 33, 9, -10749, }, /* 390 */
+ { 33, 9, -10783, }, /* 391 */
+ { 33, 9, -10782, }, /* 392 */
+ { 33, 9, -10815, }, /* 393 */
+ { 10, 5, 0, }, /* 394 */
+ { 10, 26, 0, }, /* 395 */
+ { 10, 12, 0, }, /* 396 */
+ { 10, 21, 0, }, /* 397 */
+ { 10, 15, 0, }, /* 398 */
+ { 16, 5, -7264, }, /* 399 */
+ { 58, 7, 0, }, /* 400 */
+ { 58, 6, 0, }, /* 401 */
+ { 58, 21, 0, }, /* 402 */
+ { 58, 12, 0, }, /* 403 */
+ { 22, 26, 0, }, /* 404 */
+ { 22, 6, 0, }, /* 405 */
+ { 22, 14, 0, }, /* 406 */
+ { 23, 12, 0, }, /* 407 */
+ { 26, 7, 0, }, /* 408 */
+ { 26, 6, 0, }, /* 409 */
+ { 29, 7, 0, }, /* 410 */
+ { 29, 6, 0, }, /* 411 */
+ { 3, 7, 0, }, /* 412 */
+ { 23, 26, 0, }, /* 413 */
+ { 29, 26, 0, }, /* 414 */
+ { 22, 7, 0, }, /* 415 */
+ { 60, 7, 0, }, /* 416 */
+ { 60, 6, 0, }, /* 417 */
+ { 60, 26, 0, }, /* 418 */
+ { 85, 7, 0, }, /* 419 */
+ { 85, 6, 0, }, /* 420 */
+ { 85, 21, 0, }, /* 421 */
+ { 76, 7, 0, }, /* 422 */
+ { 76, 6, 0, }, /* 423 */
+ { 76, 21, 0, }, /* 424 */
+ { 76, 13, 0, }, /* 425 */
+ { 12, 7, 0, }, /* 426 */
+ { 12, 21, 0, }, /* 427 */
+ { 78, 7, 0, }, /* 428 */
+ { 78, 14, 0, }, /* 429 */
+ { 78, 12, 0, }, /* 430 */
+ { 78, 21, 0, }, /* 431 */
+ { 33, 9, -35332, }, /* 432 */
+ { 33, 9, -42280, }, /* 433 */
+ { 48, 7, 0, }, /* 434 */
+ { 48, 12, 0, }, /* 435 */
+ { 48, 10, 0, }, /* 436 */
+ { 48, 26, 0, }, /* 437 */
+ { 64, 7, 0, }, /* 438 */
+ { 64, 21, 0, }, /* 439 */
+ { 74, 10, 0, }, /* 440 */
+ { 74, 7, 0, }, /* 441 */
+ { 74, 12, 0, }, /* 442 */
+ { 74, 21, 0, }, /* 443 */
+ { 74, 13, 0, }, /* 444 */
+ { 14, 21, 0, }, /* 445 */
+ { 68, 13, 0, }, /* 446 */
+ { 68, 7, 0, }, /* 447 */
+ { 68, 12, 0, }, /* 448 */
+ { 68, 21, 0, }, /* 449 */
+ { 73, 7, 0, }, /* 450 */
+ { 73, 12, 0, }, /* 451 */
+ { 73, 10, 0, }, /* 452 */
+ { 73, 21, 0, }, /* 453 */
+ { 83, 12, 0, }, /* 454 */
+ { 83, 10, 0, }, /* 455 */
+ { 83, 7, 0, }, /* 456 */
+ { 83, 21, 0, }, /* 457 */
+ { 83, 6, 0, }, /* 458 */
+ { 83, 13, 0, }, /* 459 */
+ { 67, 7, 0, }, /* 460 */
+ { 67, 12, 0, }, /* 461 */
+ { 67, 10, 0, }, /* 462 */
+ { 67, 13, 0, }, /* 463 */
+ { 67, 21, 0, }, /* 464 */
+ { 38, 6, 0, }, /* 465 */
+ { 91, 7, 0, }, /* 466 */
+ { 91, 12, 0, }, /* 467 */
+ { 91, 6, 0, }, /* 468 */
+ { 91, 21, 0, }, /* 469 */
+ { 86, 7, 0, }, /* 470 */
+ { 86, 10, 0, }, /* 471 */
+ { 86, 12, 0, }, /* 472 */
+ { 86, 21, 0, }, /* 473 */
+ { 86, 13, 0, }, /* 474 */
+ { 9, 4, 0, }, /* 475 */
+ { 9, 3, 0, }, /* 476 */
+ { 25, 25, 0, }, /* 477 */
+ { 0, 24, 0, }, /* 478 */
+ { 35, 7, 0, }, /* 479 */
+ { 19, 14, 0, }, /* 480 */
+ { 19, 15, 0, }, /* 481 */
+ { 19, 26, 0, }, /* 482 */
+ { 70, 7, 0, }, /* 483 */
+ { 66, 7, 0, }, /* 484 */
+ { 41, 7, 0, }, /* 485 */
+ { 41, 15, 0, }, /* 486 */
+ { 18, 7, 0, }, /* 487 */
+ { 18, 14, 0, }, /* 488 */
+ { 59, 7, 0, }, /* 489 */
+ { 59, 21, 0, }, /* 490 */
+ { 42, 7, 0, }, /* 491 */
+ { 42, 21, 0, }, /* 492 */
+ { 42, 14, 0, }, /* 493 */
+ { 13, 9, 40, }, /* 494 */
+ { 13, 5, -40, }, /* 495 */
+ { 46, 7, 0, }, /* 496 */
+ { 44, 7, 0, }, /* 497 */
+ { 44, 13, 0, }, /* 498 */
+ { 11, 7, 0, }, /* 499 */
+ { 80, 7, 0, }, /* 500 */
+ { 80, 21, 0, }, /* 501 */
+ { 80, 15, 0, }, /* 502 */
+ { 65, 7, 0, }, /* 503 */
+ { 65, 15, 0, }, /* 504 */
+ { 65, 21, 0, }, /* 505 */
+ { 71, 7, 0, }, /* 506 */
+ { 71, 21, 0, }, /* 507 */
+ { 30, 7, 0, }, /* 508 */
+ { 30, 12, 0, }, /* 509 */
+ { 30, 15, 0, }, /* 510 */
+ { 30, 21, 0, }, /* 511 */
+ { 87, 7, 0, }, /* 512 */
+ { 87, 15, 0, }, /* 513 */
+ { 87, 21, 0, }, /* 514 */
+ { 77, 7, 0, }, /* 515 */
+ { 77, 21, 0, }, /* 516 */
+ { 82, 7, 0, }, /* 517 */
+ { 82, 15, 0, }, /* 518 */
+ { 81, 7, 0, }, /* 519 */
+ { 81, 15, 0, }, /* 520 */
+ { 88, 7, 0, }, /* 521 */
+ { 0, 15, 0, }, /* 522 */
+ { 93, 10, 0, }, /* 523 */
+ { 93, 12, 0, }, /* 524 */
+ { 93, 7, 0, }, /* 525 */
+ { 93, 21, 0, }, /* 526 */
+ { 93, 15, 0, }, /* 527 */
+ { 93, 13, 0, }, /* 528 */
+ { 84, 12, 0, }, /* 529 */
+ { 84, 10, 0, }, /* 530 */
+ { 84, 7, 0, }, /* 531 */
+ { 84, 21, 0, }, /* 532 */
+ { 84, 1, 0, }, /* 533 */
+ { 62, 7, 0, }, /* 534 */
+ { 62, 14, 0, }, /* 535 */
+ { 62, 21, 0, }, /* 536 */
+ { 79, 7, 0, }, /* 537 */
+ { 19, 12, 0, }, /* 538 */
+ { 26, 26, 0, }, /* 539 */
+};
+
+const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
+ 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */
+ 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */
+ 75, 75, 65, 76, 65, 65, 77, 17, 78, 79, 80, 81, 82, 83, 84, 85, /* U+2800 */
+ 86, 87, 88, 89, 90, 91, 92, 70, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+4000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, /* U+4800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+9000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 95, /* U+9800 */
+ 96, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99,100,101,102,103, /* U+A000 */
+104,105,106,107,108,109,110,111, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,112, /* U+D000 */
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, /* U+D800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F000 */
+114,114, 93, 93,115,116,117,118,119,119,120,121,122,123,124,125, /* U+F800 */
+126,127,128,129, 17,130,131,132,133,134, 17, 17, 17, 17, 17, 17, /* U+10000 */
+135, 17,136, 17,137, 17,138, 17,139, 17, 17, 17,140, 17, 17, 17, /* U+10800 */
+141,142, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11800 */
+143,143,143,143,143,143,144, 17,145, 17, 17, 17, 17, 17, 17, 17, /* U+12000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+12800 */
+146,146,146,146,146,146,146,146,147, 17, 17, 17, 17, 17, 17, 17, /* U+13000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+13800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16000 */
+148,148,148,148,149, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A800 */
+150, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C800 */
+ 70,151,152,153,154, 17,155, 17,156,157,158,159,160,161,162,163, /* U+1D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E800 */
+164,165,166,167,168, 17,169,170,171,172,173,174,175,176,177, 17, /* U+1F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,178, 93, 93, /* U+2A000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+2A800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,179, 93, /* U+2B000 */
+180, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F000 */
+ 93, 93, 93, 93,180, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF800 */
+181, 17,182,183, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FF000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,184, /* U+FF800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10F000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,184, /* U+10F800 */
+};
+
+const pcre_uint16 PRIV(ucd_stage2)[] = { /* 47360 bytes, block = 128 */
+/* block 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11,
+ 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 0,
+
+/* block 1 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 3, 3, 3, 3, 13, 13, 10, 13, 14, 15, 6, 16, 13, 10,
+ 13, 6, 17, 17, 10, 18, 13, 2, 10, 17, 14, 19, 17, 17, 17, 2,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 14,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 20,
+
+/* block 2 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 23, 24, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, 21,
+ 22, 21, 22, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 25, 21, 22, 21, 22, 21, 22, 26,
+
+/* block 3 */
+ 27, 28, 21, 22, 21, 22, 29, 21, 22, 30, 30, 21, 22, 14, 31, 32,
+ 33, 21, 22, 30, 34, 35, 36, 37, 21, 22, 38, 14, 36, 39, 40, 41,
+ 21, 22, 21, 22, 21, 22, 42, 21, 22, 42, 14, 14, 21, 22, 42, 21,
+ 22, 43, 43, 21, 22, 21, 22, 44, 21, 22, 14, 45, 21, 22, 14, 46,
+ 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 21, 22, 21,
+ 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 50, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 14, 47, 48, 49, 21, 22, 51, 52, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 4 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 53, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 14, 14, 14, 14, 14, 14, 54, 21, 22, 55, 56, 57,
+ 57, 21, 22, 58, 59, 60, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 61, 62, 63, 64, 65, 14, 66, 66, 14, 67, 14, 68, 14, 14, 14, 14,
+ 66, 14, 14, 69, 14, 70, 14, 14, 71, 72, 14, 73, 14, 14, 14, 72,
+ 14, 74, 75, 14, 14, 76, 14, 14, 14, 14, 14, 14, 14, 77, 14, 14,
+
+/* block 5 */
+ 78, 14, 14, 78, 14, 14, 14, 14, 78, 79, 80, 80, 81, 14, 14, 14,
+ 14, 14, 82, 14, 45, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 83, 83, 83, 83, 83, 10, 10, 10, 10, 10, 85, 85, 84, 10, 84, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+
+/* block 6 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 88, 89, 88, 89, 84, 90, 88, 89, 91, 91, 92, 93, 93, 93, 2, 91,
+
+/* block 7 */
+ 91, 91, 91, 91, 90, 10, 94, 2, 95, 95, 95, 91, 96, 91, 97, 97,
+ 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 91, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,101,
+ 98,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,103,102,102,102,102,102,102,102,102,102,104,105,105,106,
+107,108,109,109,109,110,111,112, 88, 89, 88, 89, 88, 89, 88, 89,
+ 88, 89,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+115,116,117, 98,118,119,120, 88, 89,121, 88, 89, 98,122,122,122,
+
+/* block 8 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+
+/* block 9 */
+127,128,129,130,130, 86, 86,130,131,131,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+132,127,128,127,128,127,128,127,128,127,128,127,128,127,128,133,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+
+/* block 10 */
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134, 91, 91,135,136,136,136,136,136,136,
+ 91,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+
+/* block 11 */
+137,137,137,137,137,137,137,138, 91, 2,139, 91, 91, 91, 91, 91,
+ 91,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,141,140,
+142,140,140,142,140,140,142,140, 91, 91, 91, 91, 91, 91, 91, 91,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143, 91, 91, 91, 91, 91,
+143,143,143,142,142, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 12 */
+144,144,144,144, 91, 91,145,145,145,146,146,147, 2,146,148,148,
+149,149,149,149,149,149,149,149,149,149,149, 2, 91, 91,146, 2,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+ 84,150,150,150,150,150,150,150,150,150,150, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86,149,149,149,149,149,149,149,149,149, 86,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,146,146,146,146,150,150,
+ 86,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 13 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,146,150,149,149,149,149,149,149,149, 16,148,149,
+149,149,149,149,149,151,151,149,149,148,149,149,149,149,150,150,
+152,152,152,152,152,152,152,152,152,152,150,150,150,148,148,150,
+
+/* block 14 */
+153,153,153,153,153,153,153,153,153,153,153,153,153,153, 91,154,
+155,156,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156, 91, 91,155,155,155,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 15 */
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,158,158,158,158,158,158,158,158,158,158,
+158,157, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+159,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,161,161,161,161,161,
+161,161,161,161,162,162,163,164,164,164,162, 91, 91, 91, 91, 91,
+
+/* block 16 */
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,166,166,166,166,167,166,166,166,166,166,
+166,166,166,166,167,166,166,166,167,166,166,166,166,166, 91, 91,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 91,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,170,170,170, 91, 91,171, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 17 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 18 */
+172,172,172,173,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,172,173,172,174,173,173,
+173,172,172,172,172,172,172,172,172,173,173,173,173,172,173,173,
+174, 86, 86,172,172,172,172,172,174,174,174,174,174,174,174,174,
+174,174,172,172, 2, 2,175,175,175,175,175,175,175,175,175,175,
+ 2,176,174,174,174,174,174,174, 91,174,174,174,174,174,174,174,
+
+/* block 19 */
+ 91,177,178,178, 91,179,179,179,179,179,179,179,179, 91, 91,179,
+179, 91, 91,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179, 91,179,179,179,179,179,179,
+179, 91,179, 91, 91, 91,179,179,179,179, 91, 91,177,179,178,178,
+178,177,177,177,177, 91, 91,178,178, 91, 91,178,178,177,179, 91,
+ 91, 91, 91, 91, 91, 91, 91,178, 91, 91, 91, 91,179,179, 91,179,
+179,179,177,177, 91, 91,180,180,180,180,180,180,180,180,180,180,
+179,179,181,181,182,182,182,182,182,182,183,181, 91, 91, 91, 91,
+
+/* block 20 */
+ 91,184,184,185, 91,186,186,186,186,186,186, 91, 91, 91, 91,186,
+186, 91, 91,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186, 91,186,186,186,186,186,186,
+186, 91,186,186, 91,186,186, 91,186,186, 91, 91,184, 91,185,185,
+185,184,184, 91, 91, 91, 91,184,184, 91, 91,184,184,184, 91, 91,
+ 91,184, 91, 91, 91, 91, 91, 91, 91,186,186,186,186, 91,186, 91,
+ 91, 91, 91, 91, 91, 91,187,187,187,187,187,187,187,187,187,187,
+184,184,186,186,186,184, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 21 */
+ 91,188,188,189, 91,190,190,190,190,190,190,190,190,190, 91,190,
+190,190, 91,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190, 91,190,190,190,190,190,190,
+190, 91,190,190, 91,190,190,190,190,190, 91, 91,188,190,189,189,
+189,188,188,188,188,188, 91,188,188,189, 91,189,189,188, 91, 91,
+190, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+190,190,188,188, 91, 91,191,191,191,191,191,191,191,191,191,191,
+ 91,192, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 22 */
+ 91,193,194,194, 91,195,195,195,195,195,195,195,195, 91, 91,195,
+195, 91, 91,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195, 91,195,195,195,195,195,195,
+195, 91,195,195, 91,195,195,195,195,195, 91, 91,193,195,194,193,
+194,193,193,193,193, 91, 91,194,194, 91, 91,194,194,193, 91, 91,
+ 91, 91, 91, 91, 91, 91,193,194, 91, 91, 91, 91,195,195, 91,195,
+195,195,193,193, 91, 91,196,196,196,196,196,196,196,196,196,196,
+197,195,198,198,198,198,198,198, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 23 */
+ 91, 91,199,200, 91,200,200,200,200,200,200, 91, 91, 91,200,200,
+200, 91,200,200,200,200, 91, 91, 91,200,200, 91,200, 91,200,200,
+ 91, 91, 91,200,200, 91, 91, 91,200,200,200, 91, 91, 91,200,200,
+200,200,200,200,200,200,200,200,200,200, 91, 91, 91, 91,201,201,
+199,201,201, 91, 91, 91,201,201,201, 91,201,201,201,199, 91, 91,
+200, 91, 91, 91, 91, 91, 91,201, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91,202,202,202,202,202,202,202,202,202,202,
+203,203,203,204,204,204,204,204,204,205,204, 91, 91, 91, 91, 91,
+
+/* block 24 */
+ 91,206,206,206, 91,207,207,207,207,207,207,207,207, 91,207,207,
+207, 91,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207, 91,207,207,207,207,207,207,
+207,207,207,207, 91,207,207,207,207,207, 91, 91, 91,207,208,208,
+208,206,206,206,206, 91,208,208,208, 91,208,208,208,208, 91, 91,
+ 91, 91, 91, 91, 91,208,208, 91,207,207, 91, 91, 91, 91, 91, 91,
+207,207,208,208, 91, 91,209,209,209,209,209,209,209,209,209,209,
+ 91, 91, 91, 91, 91, 91, 91, 91,210,210,210,210,210,210,210,211,
+
+/* block 25 */
+ 91, 91,212,212, 91,213,213,213,213,213,213,213,213, 91,213,213,
+213, 91,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213, 91,213,213,213,213,213,213,
+213,213,213,213, 91,213,213,213,213,213, 91, 91,214,213,212,214,
+212,212,212,212,212, 91,214,212,212, 91,212,212,214,214, 91, 91,
+ 91, 91, 91, 91, 91,212,212, 91, 91, 91, 91, 91, 91, 91,213, 91,
+213,213,214,214, 91, 91,215,215,215,215,215,215,215,215,215,215,
+ 91,213,213, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 26 */
+ 91, 91,216,216, 91,217,217,217,217,217,217,217,217, 91,217,217,
+217, 91,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217, 91, 91,217,216,216,
+216,218,218,218,218, 91,216,216,216, 91,216,216,216,218,217, 91,
+ 91, 91, 91, 91, 91, 91, 91,216, 91, 91, 91, 91, 91, 91, 91, 91,
+217,217,218,218, 91, 91,219,219,219,219,219,219,219,219,219,219,
+220,220,220,220,220,220, 91, 91, 91,221,217,217,217,217,217,217,
+
+/* block 27 */
+ 91, 91,222,222, 91,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223, 91, 91, 91,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223, 91,223,223,223,223,223,223,223,223,223, 91,223, 91, 91,
+223,223,223,223,223,223,223, 91, 91, 91,224, 91, 91, 91, 91,222,
+222,222,224,224,224, 91,224, 91,222,222,222,222,222,222,222,222,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91,222,222,225, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 28 */
+ 91,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,227,226,226,227,227,227,227,227,227,227, 91, 91, 91, 91, 3,
+226,226,226,226,226,226,228,227,227,227,227,227,227,227,227,229,
+230,230,230,230,230,230,230,230,230,230,229,229, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 29 */
+ 91,231,231, 91,231, 91, 91,231,231, 91,231, 91, 91,231, 91, 91,
+ 91, 91, 91, 91,231,231,231,231, 91,231,231,231,231,231,231,231,
+ 91,231,231,231, 91,231, 91,231, 91, 91,231,231, 91,231,231,231,
+231,232,231,231,232,232,232,232,232,232, 91,232,232,231, 91, 91,
+231,231,231,231,231, 91,233, 91,232,232,232,232,232,232, 91, 91,
+234,234,234,234,234,234,234,234,234,234, 91, 91,231,231, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 30 */
+235,236,236,236,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,236,236,236,236,236,238,238,236,236,236,236,236,236,
+239,239,239,239,239,239,239,239,239,239,240,240,240,240,240,240,
+240,240,240,240,236,238,236,238,236,238,241,242,241,242,243,243,
+235,235,235,235,235,235,235,235, 91,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235, 91, 91, 91,
+ 91,238,238,238,238,238,238,238,238,238,238,238,238,238,238,243,
+
+/* block 31 */
+238,238,238,238,238,237,238,238,235,235,235,235,235,238,238,238,
+238,238,238,238,238,238,238,238, 91,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238, 91,236,236,
+236,236,236,236,236,236,238,236,236,236,236,236,236, 91,236,236,
+237,237,237,237,237, 13, 13, 13, 13,237,237, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 32 */
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,245,245,246,246,246,
+246,245,246,246,246,246,246,246,245,246,246,245,245,246,246,244,
+247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,
+244,244,244,244,244,244,245,245,246,246,244,244,244,244,246,246,
+246,244,245,245,245,244,244,245,245,245,245,245,245,245,244,244,
+244,246,246,246,246,244,244,244,244,244,244,244,244,244,244,244,
+
+/* block 33 */
+244,244,246,245,245,246,246,245,245,245,245,245,245,246,244,245,
+247,247,247,247,247,247,247,247,247,247,245,245,245,246,249,249,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251, 2,252, 91, 91, 91,
+
+/* block 34 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+
+/* block 35 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254, 91,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+
+/* block 36 */
+254,254,254,254,254,254,254,254,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254, 91,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+
+/* block 37 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254, 91, 91,255,255,255,
+256,257,257,257,257,257,257,257,257,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258, 91, 91, 91,
+
+/* block 38 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+256,256,256,256,256,256,256,256,256,256, 91, 91, 91, 91, 91, 91,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 39 */
+260,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 40 */
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 41 */
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,262,262,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 42 */
+263,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,
+264,264,264,264,264,264,264,264,264,264,264,265,266, 91, 91, 91,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267, 2, 2, 2,268,268,
+268, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 43 */
+269,269,269,269,269,269,269,269,269,269,269,269,269, 91,269,269,
+269,269,270,270,270, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,272,272,272, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,
+273,273,274,274, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+275,275,275,275,275,275,275,275,275,275,275,275,275, 91,275,275,
+275, 91,276,276, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 44 */
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,278,278,279,280,280,280,280,280,280,280,279,279,
+279,279,279,279,279,279,280,279,279,280,280,280,280,280,280,280,
+280,280,280,280,281,281,281,282,281,281,281,283,277,280, 91, 91,
+284,284,284,284,284,284,284,284,284,284, 91, 91, 91, 91, 91, 91,
+285,285,285,285,285,285,285,285,285,285, 91, 91, 91, 91, 91, 91,
+
+/* block 45 */
+286,286, 2, 2,286, 2,287,286,286,286,286,288,288,288,289, 91,
+290,290,290,290,290,290,290,290,290,290, 91, 91, 91, 91, 91, 91,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,292,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 46 */
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,288,291, 91, 91, 91, 91, 91,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 47 */
+293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,
+293,293,293,293,293,293,293,293,293,293,293,293,293, 91, 91, 91,
+294,294,294,295,295,295,295,294,294,295,295,295, 91, 91, 91, 91,
+295,295,294,295,295,295,295,295,295,294,294,294, 91, 91, 91, 91,
+296, 91, 91, 91,297,297,298,298,298,298,298,298,298,298,298,298,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299, 91, 91,
+299,299,299,299,299, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 48 */
+300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,300,300, 91, 91, 91, 91,
+301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,
+301,300,300,300,300,300,300,300,301,301, 91, 91, 91, 91, 91, 91,
+302,302,302,302,302,302,302,302,302,302,303, 91, 91, 91,304,304,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+
+/* block 49 */
+306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
+306,306,306,306,306,306,306,307,307,308,308,308, 91, 91,309,309,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,311,312,311,312,312,312,312,312,312,312, 91,
+312,311,312,311,311,312,312,312,312,312,312,312,312,311,311,311,
+311,311,311,312,312,312,312,312,312,312,312,312,312, 91, 91,312,
+
+/* block 50 */
+313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91,
+313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91,
+314,314,314,314,314,314,314,315,314,314,314,314,314,314, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 51 */
+316,316,316,316,317,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,316,317,316,316,316,316,316,317,316,317,317,317,
+317,317,316,317,317,318,318,318,318,318,318,318, 91, 91, 91, 91,
+319,319,319,319,319,319,319,319,319,319,320,320,320,320,320,320,
+320,321,321,321,321,321,321,321,321,321,321,316,316,316,316,316,
+316,316,316,316,321,321,321,321,321,321,321,321,321, 91, 91, 91,
+
+/* block 52 */
+322,322,323,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,323,322,322,322,322,323,323,322,322,323, 91, 91, 91,324,324,
+325,325,325,325,325,325,325,325,325,325, 91, 91, 91, 91, 91, 91,
+326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,
+326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,
+326,326,326,326,326,326,327,328,327,327,328,328,328,327,328,327,
+327,327,328,328, 91, 91, 91, 91, 91, 91, 91, 91,329,329,329,329,
+
+/* block 53 */
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,331,331,331,331,331,331,331,331,332,332,332,332,
+332,332,332,332,331,331,332,332, 91, 91, 91,333,333,333,333,333,
+334,334,334,334,334,334,334,334,334,334, 91, 91, 91,330,330,330,
+335,335,335,335,335,335,335,335,335,335,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,337,337,337,337,337,337,338,338,
+
+/* block 54 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86,339, 86, 86, 86, 86, 86, 86, 86,340,340,340,340, 86,340,340,
+340,340,339, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 55 */
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 98, 98, 98, 98, 98,341, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92, 92, 92,
+ 92, 92, 14, 14, 14, 14, 98, 98, 98, 98, 98, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,342,343, 14, 14, 14,344, 14, 14,
+
+/* block 56 */
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 86, 86, 86, 86,
+
+/* block 57 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 58 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 14, 14, 14, 14, 14,345, 14, 14,346, 14,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 59 */
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91,
+ 98,347, 98,347, 98,347, 98,347, 91,348, 91,348, 91,348, 91,348,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+349,349,350,350,350,350,351,351,352,352,353,353,354,354, 91, 91,
+
+/* block 60 */
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347, 98,356, 98, 91, 98, 98,348,348,357,357,358, 90,359, 90,
+ 90, 90, 98,356, 98, 91, 98, 98,360,360,360,360,358, 90, 90, 90,
+347,347, 98, 98, 91, 91, 98, 98,348,348,361,361, 91, 90, 90, 90,
+347,347, 98, 98, 98,117, 98, 98,348,348,362,362,121, 90, 90, 90,
+ 91, 91, 98,356, 98, 91, 98, 98,363,363,364,364,358, 90, 90, 91,
+
+/* block 61 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,365,365, 16, 16,
+ 7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15,
+ 2, 2, 2, 2, 2, 2, 2, 2,366,367, 16, 16, 16, 16, 16, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11,
+ 11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 16, 16, 16, 16, 16, 91, 91, 91, 91, 91, 16, 16, 16, 16, 16, 16,
+ 17, 83, 91, 91, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 83,
+
+/* block 62 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 91,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 91, 91, 91,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,368,368,368,
+368, 86,368,368,368, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 63 */
+ 13, 13,369, 13, 13, 13, 13,369, 13, 13,370,369,369,369,370,370,
+369,369,369,370, 13,369, 13, 13, 6,369,369,369,369,369, 13, 13,
+ 13, 13, 13, 13,369, 13,371, 13,369, 13,372,373,369,369, 13,370,
+369,369,374,369,370,340,340,340,340,370, 13, 13,370,370,369,369,
+ 6, 6, 6, 6, 6,369,370,370,370,370, 13, 6, 13, 13,375, 13,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,
+
+/* block 64 */
+378,378,378, 21, 22,378,378,378,378, 17, 91, 91, 91, 91, 91, 91,
+ 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13,
+ 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6,
+ 13, 13, 6, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 65 */
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 66 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 13, 13, 13, 13, 13, 13, 13, 4, 5, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13,
+
+/* block 67 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6,
+ 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 68 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 69 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13,379,379,379,379,379,379,379,379,379,379,
+379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,
+380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
+380,380,380,380,380,380,380,380,380,380, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 70 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 71 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 72 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 73 */
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5,
+ 4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 74 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 91, 6, 91, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 75 */
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+
+/* block 76 */
+ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
+ 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6,
+
+/* block 77 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 78 */
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, 91,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, 91,
+ 21, 22,384,385,386,387,388, 21, 22, 21, 22, 21, 22,389,390,391,
+392, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 83,393,393,
+
+/* block 79 */
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,394,395,395,395,395,395,395,113,114,113,114,396,
+396,396, 91, 91, 91, 91, 91, 91, 91,397,397,397,397,398,397,397,
+
+/* block 80 */
+399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
+399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
+399,399,399,399,399,399, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400, 91, 91, 91, 91, 91, 91, 91, 91, 91,401,
+402, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,403,
+
+/* block 81 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+
+/* block 82 */
+ 2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2,
+ 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 84,
+ 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 83 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404, 91,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 84 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+
+/* block 85 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+
+/* block 86 */
+ 1, 2, 2, 2, 13,405,340,406, 4, 5, 4, 5, 4, 5, 4, 5,
+ 4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5,
+ 13,406,406,406,406,406,406,406,406,406, 86, 86, 86, 86,407,407,
+ 7, 84, 84, 84, 84, 84, 13, 13,406,406,406,405,340, 2, 13, 13,
+ 91,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+
+/* block 87 */
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408, 91, 91, 86, 86, 10, 10,409,409,408,
+ 7,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410, 2, 84,411,411,410,
+
+/* block 88 */
+ 91, 91, 91, 91, 91,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412, 91, 91,
+ 91,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+
+/* block 89 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 91,
+ 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+
+/* block 90 */
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 13,
+
+/* block 91 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 91,
+
+/* block 92 */
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 93 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 94 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 95 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 96 */
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,417,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+
+/* block 97 */
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+
+/* block 98 */
+416,416,416,416,416,416,416,416,416,416,416,416,416, 91, 91, 91,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,420,420,420,420,420,420,421,421,
+
+/* block 99 */
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+
+/* block 100 */
+422,422,422,422,422,422,422,422,422,422,422,422,423,424,424,424,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+425,425,425,425,425,425,425,425,425,425,422,422, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,426,130,
+131,131,131,427, 91, 91, 91, 91, 91, 91, 91, 91,130,130,427,342,
+
+/* block 101 */
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,429,
+430,430,431,431,431,431,431,431, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 102 */
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 10, 10, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 14, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 83, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,432, 21, 22,
+
+/* block 103 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 84, 10, 10, 21, 22,433, 14, 91,
+ 21, 22, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 14, 45, 45, 45, 45, 45,
+
+/* block 104 */
+434,434,435,434,434,434,435,434,434,434,434,435,434,434,434,434,
+434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,
+434,434,434,436,436,435,435,436,437,437,437,437, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 91, 91, 91, 91, 91, 91,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,439,439,439,439, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 105 */
+440,440,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,442, 91, 91, 91, 91, 91, 91, 91, 91, 91,443,443,
+444,444,444,444,444,444,444,444,444,444, 91, 91, 91, 91, 91, 91,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,174,174,174,174,174,174,445,445,445,174, 91, 91, 91, 91,
+
+/* block 106 */
+446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,
+447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,
+447,447,447,447,447,447,448,448,448,448,448,448,448,448,449,449,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,451,451,451,451,451,451,451,451,451,
+451,451,452,452, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,453,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253, 91, 91, 91,
+
+/* block 107 */
+454,454,454,455,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,454,455,455,454,454,454,454,455,455,454,455,455,455,
+455,457,457,457,457,457,457,457,457,457,457,457,457,457, 91,458,
+459,459,459,459,459,459,459,459,459,459, 91, 91, 91, 91,457,457,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 108 */
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,461,461,461,461,461,461,462,
+462,461,461,462,462,461,461, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+460,460,460,461,460,460,460,460,460,460,460,460,461,462, 91, 91,
+463,463,463,463,463,463,463,463,463,463, 91, 91,464,464,464,464,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+465,244,244,244,244,244,244,249,249,249,244,245, 91, 91, 91, 91,
+
+/* block 109 */
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+467,466,467,467,467,466,466,467,467,466,466,466,466,466,467,467,
+466,467,466, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,466,466,468,469,469,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 110 */
+ 91,254,254,254,254,254,254, 91, 91,254,254,254,254,254,254, 91,
+ 91,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 111 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,471,471,472,471,471,472,471,471,473,471,472, 91, 91,
+474,474,474,474,474,474,474,474,474,474, 91, 91, 91, 91, 91, 91,
+
+/* block 112 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253, 91, 91, 91, 91,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253, 91, 91, 91, 91,
+
+/* block 113 */
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+
+/* block 114 */
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+
+/* block 115 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 116 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 117 */
+ 14, 14, 14, 14, 14, 14, 14, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91,138,138,138,138,138, 91, 91, 91, 91, 91,143,140,143,
+143,143,143,143,143,143,143,143,143,477,143,143,143,143,143,143,
+143,143,143,143,143,143,143, 91,143,143,143,143,143, 91,143, 91,
+143,143, 91,143,143, 91,143,143,143,143,143,143,143,143,143,143,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 118 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
+478,478, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 119 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 120 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150, 4, 5,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 121 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+ 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+150,150,150,150,150,150,150,150,150,150,150,150,147, 13, 91, 91,
+
+/* block 122 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
+ 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11,
+ 2, 2, 2, 91, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2,
+ 2, 2, 6, 7, 6, 6, 6, 91, 2, 3, 2, 2, 91, 91, 91, 91,
+150,150,150,150,150, 91,150,150,150,150,150,150,150,150,150,150,
+
+/* block 123 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150, 91, 91, 16,
+
+/* block 124 */
+ 91, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11,
+ 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4,
+ 5, 2, 4, 5, 2, 2,410,410,410,410,410,410,410,410,410,410,
+ 84,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+
+/* block 125 */
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410, 84, 84,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 91,
+ 91, 91,253,253,253,253,253,253, 91, 91,253,253,253,253,253,253,
+ 91, 91,253,253,253,253,253,253, 91, 91,253,253,253, 91, 91, 91,
+ 3, 3, 6, 10, 13, 3, 3, 91, 13, 6, 6, 6, 6, 13, 13, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 16, 16, 16, 13, 13, 91, 91,
+
+/* block 126 */
+479,479,479,479,479,479,479,479,479,479,479,479, 91,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479, 91,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479, 91,479,479, 91,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 127 */
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479, 91, 91, 91, 91, 91,
+
+/* block 128 */
+ 2, 2, 13, 91, 91, 91, 91, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,481,481,481,481,482,482,482,482,482,482,482,
+
+/* block 129 */
+482,482,482,482,482,482,482,482,482,482,481, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 91, 91,
+
+/* block 130 */
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483,483,483,483,483,483,483,483,483,483,483,483, 91, 91, 91,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 131 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, 91,
+486,486,486,486, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,488,487,487,487,487,487,487,487,487,488, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 132 */
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489, 91,490,
+491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
+491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
+491,491,491,491, 91, 91, 91, 91,491,491,491,491,491,491,491,491,
+492,493,493,493,493,493, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 133 */
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,495,495,495,495,495,495,495,495,
+495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
+495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+
+/* block 134 */
+497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,
+497,497,497,497,497,497,497,497,497,497,497,497,497,497, 91, 91,
+498,498,498,498,498,498,498,498,498,498, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 135 */
+499,499,499,499,499,499, 91, 91,499, 91,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499, 91,499,499, 91, 91, 91,499, 91, 91,499,
+500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,
+500,500,500,500,500,500, 91,501,502,502,502,502,502,502,502,502,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 136 */
+503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,
+503,503,503,503,503,503,504,504,504,504,504,504, 91, 91, 91,505,
+506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,
+506,506,506,506,506,506,506,506,506,506, 91, 91, 91, 91, 91,507,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 137 */
+508,509,509,509, 91,509,509, 91, 91, 91, 91, 91,509,509,509,509,
+508,508,508,508, 91,508,508,508, 91,508,508,508,508,508,508,508,
+508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,
+508,508,508,508, 91, 91, 91, 91,509,509,509, 91, 91, 91, 91,509,
+510,510,510,510,510,510,510,510, 91, 91, 91, 91, 91, 91, 91, 91,
+511,511,511,511,511,511,511,511,511, 91, 91, 91, 91, 91, 91, 91,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,513,513,514,
+
+/* block 138 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515, 91, 91, 91,516,516,516,516,516,516,516,
+517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,
+517,517,517,517,517,517, 91, 91,518,518,518,518,518,518,518,518,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519, 91, 91, 91, 91, 91,520,520,520,520,520,520,520,520,
+
+/* block 139 */
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 140 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, 91,
+
+/* block 141 */
+523,524,523,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,524,524,524,524,524,524,524,524,
+524,524,524,524,524,524,524,526,526,526,526,526,526,526, 91, 91,
+ 91, 91,527,527,527,527,527,527,527,527,527,527,527,527,527,527,
+527,527,527,527,527,527,528,528,528,528,528,528,528,528,528,528,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 142 */
+529,529,530,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+530,530,530,529,529,529,529,530,530,529,529,532,532,533,532,532,
+532,532, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 143 */
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+
+/* block 144 */
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 145 */
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+536,536,536,536, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 146 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+
+/* block 147 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 148 */
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+
+/* block 149 */
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 150 */
+410,408, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 151 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 152 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13,339,339, 86, 86, 86, 13, 13, 13,339,339,339,
+339,339,339, 16, 16, 16, 16, 16, 16, 16, 16, 86, 86, 86, 86, 86,
+
+/* block 153 */
+ 86, 86, 86, 13, 13, 86, 86, 86, 86, 86, 86, 86, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 86, 86, 86, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 154 */
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,538,538,538,482, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 155 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 156 */
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,370,370,
+370,370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 157 */
+369,369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369, 91,369,369,
+ 91, 91,369, 91, 91,369,369, 91, 91,369,369,369,369, 91,369,369,
+369,369,369,369,369,369,370,370,370,370, 91,370, 91,370,370,370,
+370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 158 */
+370,370,370,370,369,369, 91,369,369,369,369, 91, 91,369,369,369,
+369,369,369,369,369, 91,369,369,369,369,369,369,369, 91,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,369,369, 91,369,369,369,369, 91,
+369,369,369,369,369, 91,369, 91, 91, 91,369,369,369,369,369,369,
+369, 91,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 159 */
+369,369,369,369,369,369,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 160 */
+370,370,370,370,370,370,370,370,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 161 */
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370, 91, 91,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369, 6,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370, 6,370,370,370,370,
+370,370,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369, 6,370,370,370,370,
+
+/* block 162 */
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370, 6,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369, 6,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, 6,
+370,370,370,370,370,370,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, 6,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 163 */
+370,370,370,370,370,370,370,370,370, 6,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369, 6,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370, 6,370,370,370,370,370,370,369,370, 91, 91, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 164 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 165 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 166 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 167 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 168 */
+539, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 169 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91,
+
+/* block 170 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 171 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 172 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 91, 91, 91,
+
+/* block 173 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 174 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13,
+
+/* block 175 */
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 13, 13, 13, 91, 13, 91, 13, 91, 13, 91, 13, 13, 13, 91,
+ 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 91, 13, 91, 91,
+ 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 176 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 177 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 178 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 179 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 180 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 181 */
+ 91, 16, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+
+/* block 182 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+/* block 183 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 184 */
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476, 91, 91,
+
+};
+
+#if UCD_BLOCK_SIZE != 128
+#error Please correct UCD_BLOCK_SIZE in pcre_internal.h
+#endif
+#endif /* SUPPORT_UCP */
diff --git a/src/3rdparty/pcre/pcre_valid_utf8.c b/src/3rdparty/pcre/pcre_valid_utf8.c
new file mode 100644
index 0000000000..b2dc5c9f1a
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_valid_utf8.c
@@ -0,0 +1,299 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF-8 character
+strings. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Validate a UTF-8 string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF-8 string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+Originally, this function checked according to RFC 2279, allowing for values in
+the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
+the canonical format. Once somebody had pointed out RFC 3629 to me (it
+obsoletes 2279), additional restrictions were applied. The values are now
+limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
+subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
+characters is still checked.
+
+From release 8.13 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF8_ERR0 No error
+PCRE_UTF8_ERR1 Missing 1 byte at the end of the string
+PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string
+PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string
+PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string
+PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string
+PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
+PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted
+PCRE_UTF8_ERR15 Overlong 2-byte sequence
+PCRE_UTF8_ERR16 Overlong 3-byte sequence
+PCRE_UTF8_ERR17 Overlong 4-byte sequence
+PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
+PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
+PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
+PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
+
+Arguments:
+ string points to the string
+ length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
+
+Returns: = 0 if the string is a valid UTF-8 string
+ > 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
+{
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
+
+if (length < 0)
+ {
+ for (p = string; *p != 0; p++);
+ length = (int)(p - string);
+ }
+
+for (p = string; length-- > 0; p++)
+ {
+ register int ab, c, d;
+
+ c = *p;
+ if (c < 128) continue; /* ASCII character */
+
+ if (c < 0xc0) /* Isolated 10xx xxxx byte */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR20;
+ }
+
+ if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR21;
+ }
+
+ ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
+ if (length < ab)
+ {
+ *erroroffset = (int)(p - string); /* Missing bytes */
+ return ab - length; /* Codes ERR1 to ERR5 */
+ }
+ length -= ab; /* Length remaining */
+
+ /* Check top bits in the second byte */
+
+ if (((d = *(++p)) & 0xc0) != 0x80)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR6;
+ }
+
+ /* For each length, check that the remaining bytes start with the 0x80 bit
+ set and not the 0x40 bit. Then check for an overlong sequence, and for the
+ excluded range 0xd800 to 0xdfff. */
+
+ switch (ab)
+ {
+ /* 2-byte character. No further bytes to check for 0x80. Check first byte
+ for for xx00 000x (overlong sequence). */
+
+ case 1: if ((c & 0x3e) == 0)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR15;
+ }
+ break;
+
+ /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
+ for 1110 0000, xx0x xxxx (overlong sequence) or
+ 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
+
+ case 2:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if (c == 0xe0 && (d & 0x20) == 0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR16;
+ }
+ if (c == 0xed && d >= 0xa0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR14;
+ }
+ break;
+
+ /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
+ bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
+ character greater than 0x0010ffff (f4 8f bf bf) */
+
+ case 3:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if (c == 0xf0 && (d & 0x30) == 0)
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR17;
+ }
+ if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR13;
+ }
+ break;
+
+ /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
+ rejected by the length test below. However, we do the appropriate tests
+ here so that overlong sequences get diagnosed, and also in case there is
+ ever an option for handling these larger code points. */
+
+ /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
+ 1111 1000, xx00 0xxx */
+
+ case 4:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if (c == 0xf8 && (d & 0x38) == 0)
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR18;
+ }
+ break;
+
+ /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
+ 1111 1100, xx00 00xx. */
+
+ case 5:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR10;
+ }
+ if (c == 0xfc && (d & 0x3c) == 0)
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR19;
+ }
+ break;
+ }
+
+ /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
+ excluded by RFC 3629. The pointer p is currently at the last byte of the
+ character. */
+
+ if (ab > 3)
+ {
+ *erroroffset = (int)(p - string) - ab;
+ return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
+ }
+ }
+
+#else /* SUPPORT_UTF */
+(void)(string); /* Keep picky compilers happy */
+(void)(length);
+#endif
+
+return PCRE_UTF8_ERR0; /* This indicates success */
+}
+
+/* End of pcre_valid_utf8.c */
diff --git a/src/3rdparty/pcre/pcre_version.c b/src/3rdparty/pcre/pcre_version.c
new file mode 100644
index 0000000000..915ae8764c
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_version.c
@@ -0,0 +1,95 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_version(), which returns a
+string that identifies the PCRE version that is in use. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return version string *
+*************************************************/
+
+/* These macros are the standard way of turning unquoted text into C strings.
+They allow macros like PCRE_MAJOR to be defined without quotes, which is
+convenient for user programs that want to test its value. */
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+/* A problem turned up with PCRE_PRERELEASE, which is defined empty for
+production releases. Originally, it was used naively in this code:
+
+ return XSTRING(PCRE_MAJOR)
+ "." XSTRING(PCRE_MINOR)
+ XSTRING(PCRE_PRERELEASE)
+ " " XSTRING(PCRE_DATE);
+
+However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of
+STRING(). The C standard states: "If (before argument substitution) any
+argument consists of no preprocessing tokens, the behavior is undefined." It
+turns out the gcc treats this case as a single empty string - which is what we
+really want - but Visual C grumbles about the lack of an argument for the
+macro. Unfortunately, both are within their rights. To cope with both ways of
+handling this, I had resort to some messy hackery that does a test at run time.
+I could find no way of detecting that a macro is defined as an empty string at
+pre-processor time. This hack uses a standard trick for avoiding calling
+the STRING macro with an empty argument when doing the test. */
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
+pcre_version(void)
+#else
+PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
+pcre16_version(void)
+#endif
+{
+return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
+ XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
+ XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
+}
+
+/* End of pcre_version.c */
diff --git a/src/3rdparty/pcre/pcre_xclass.c b/src/3rdparty/pcre/pcre_xclass.c
new file mode 100644
index 0000000000..45f1c5b152
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_xclass.c
@@ -0,0 +1,198 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Match character against an XCLASS *
+*************************************************/
+
+/* This function is called to match a character against an extended class that
+might contain values > 255 and/or Unicode properties.
+
+Arguments:
+ c the character
+ data points to the flag byte of the XCLASS data
+
+Returns: TRUE if character matches, else FALSE
+*/
+
+BOOL
+PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
+{
+int t;
+BOOL negated = (*data & XCL_NOT) != 0;
+
+(void)utf;
+#ifdef COMPILE_PCRE8
+/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
+utf = TRUE;
+#endif
+
+/* Character values < 256 are matched against a bitmap, if one is present. If
+not, we still carry on, because there may be ranges that start below 256 in the
+additional data. */
+
+if (c < 256)
+ {
+ if ((*data & XCL_MAP) != 0 &&
+ (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
+ return !negated; /* char found */
+ }
+
+/* First skip the bit map if present. Then match against the list of Unicode
+properties or large chars or ranges that end with a large char. We won't ever
+encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
+
+if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
+
+while ((t = *data++) != XCL_END)
+ {
+ int x, y;
+ if (t == XCL_SINGLE)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ x = *data++;
+ if (c == x) return !negated;
+ }
+ else if (t == XCL_RANGE)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ GETCHARINC(y, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ {
+ x = *data++;
+ y = *data++;
+ }
+ if (c >= x && c <= y) return !negated;
+ }
+
+#ifdef SUPPORT_UCP
+ else /* XCL_PROP & XCL_NOTPROP */
+ {
+ const ucd_record *prop = GET_UCD(c);
+
+ switch(*data)
+ {
+ case PT_ANY:
+ if (t == XCL_PROP) return !negated;
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_GC:
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_PC:
+ if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_SC:
+ if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
+ == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ /* This should never occur, but compilers may mutter if there is no
+ default. */
+
+ default:
+ return FALSE;
+ }
+
+ data += 2;
+ }
+#endif /* SUPPORT_UCP */
+ }
+
+return negated; /* char did not match */
+}
+
+/* End of pcre_xclass.c */
diff --git a/src/3rdparty/pcre/sljit/sljitConfig.h b/src/3rdparty/pcre/sljit/sljitConfig.h
new file mode 100644
index 0000000000..c832dfe60d
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitConfig.h
@@ -0,0 +1,96 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_H_
+#define _SLJIT_CONFIG_H_
+
+/* --------------------------------------------------------------------- */
+/* Architecture */
+/* --------------------------------------------------------------------- */
+
+/* Architecture selection */
+/* #define SLJIT_CONFIG_X86_32 1 */
+/* #define SLJIT_CONFIG_X86_64 1 */
+/* #define SLJIT_CONFIG_ARM_V5 1 */
+/* #define SLJIT_CONFIG_ARM_V7 1 */
+/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
+/* #define SLJIT_CONFIG_PPC_32 1 */
+/* #define SLJIT_CONFIG_PPC_64 1 */
+/* #define SLJIT_CONFIG_MIPS_32 1 */
+
+/* #define SLJIT_CONFIG_AUTO 1 */
+/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
+
+/* --------------------------------------------------------------------- */
+/* Utilities */
+/* --------------------------------------------------------------------- */
+
+/* Useful for thread-safe compiling of global functions. */
+#ifndef SLJIT_UTIL_GLOBAL_LOCK
+/* Enabled by default */
+#define SLJIT_UTIL_GLOBAL_LOCK 1
+#endif
+
+/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
+#ifndef SLJIT_UTIL_STACK
+/* Enabled by default */
+#define SLJIT_UTIL_STACK 1
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Configuration */
+/* --------------------------------------------------------------------- */
+
+/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should
+ define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */
+#ifndef SLJIT_STD_MACROS_DEFINED
+/* Disabled by default. */
+#define SLJIT_STD_MACROS_DEFINED 0
+#endif
+
+/* Executable code allocation:
+ If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
+ define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */
+#ifndef SLJIT_EXECUTABLE_ALLOCATOR
+/* Enabled by default. */
+#define SLJIT_EXECUTABLE_ALLOCATOR 1
+#endif
+
+/* Debug checks (assertions, etc.). */
+#ifndef SLJIT_DEBUG
+/* Enabled by default */
+#define SLJIT_DEBUG 1
+#endif
+
+/* Verbose operations */
+#ifndef SLJIT_VERBOSE
+/* Enabled by default */
+#define SLJIT_VERBOSE 1
+#endif
+
+/* See the beginning of sljitConfigInternal.h */
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitConfigInternal.h b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
new file mode 100644
index 0000000000..de6e9f07e2
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
@@ -0,0 +1,424 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_INTERNAL_H_
+#define _SLJIT_CONFIG_INTERNAL_H_
+
+/*
+ SLJIT defines the following macros depending on the target architecture:
+
+ Feature detection (boolean) macros:
+ SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
+ SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
+ SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index
+ SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index
+ SLJIT_LITTLE_ENDIAN : little endian architecture
+ SLJIT_BIG_ENDIAN : big endian architecture
+ SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
+ SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
+
+ Types and useful macros:
+ sljit_b, sljit_ub : signed and unsigned 8 bit byte
+ sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type
+ sljit_i, sljit_ui : signed and unsigned 32 bit integer type
+ sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t)
+ SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
+ SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
+*/
+
+#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
+#error "An architecture must be selected"
+#endif
+
+/* Sanity check. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
+#error "Multiple architectures are selected"
+#endif
+
+/* Auto select option (requires compiler support) */
+#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
+
+#ifndef _WIN32
+
+#if defined(__i386__) || defined(__i386)
+#define SLJIT_CONFIG_X86_32 1
+#elif defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(__arm__) || defined(__ARM__)
+#ifdef __thumb2__
+#define SLJIT_CONFIG_ARM_THUMB2 1
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
+#define SLJIT_CONFIG_ARM_V7 1
+#else
+#define SLJIT_CONFIG_ARM_V5 1
+#endif
+#elif defined(__ppc64__) || defined(__powerpc64__)
+#define SLJIT_CONFIG_PPC_64 1
+#elif defined(__ppc__) || defined(__powerpc__)
+#define SLJIT_CONFIG_PPC_32 1
+#elif defined(__mips__)
+#define SLJIT_CONFIG_MIPS_32 1
+#else
+/* Unsupported architecture */
+#define SLJIT_CONFIG_UNSUPPORTED 1
+#endif
+
+#else /* !_WIN32 */
+
+#if defined(_M_X64) || defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(_ARM_)
+#define SLJIT_CONFIG_ARM_V5 1
+#else
+#define SLJIT_CONFIG_X86_32 1
+#endif
+
+#endif /* !WIN32 */
+#endif /* SLJIT_CONFIG_AUTO */
+
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+#undef SLJIT_EXECUTABLE_ALLOCATOR
+#endif
+
+#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
+
+/* These libraries are needed for the macros below. */
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* STD_MACROS_DEFINED */
+
+/* General macros:
+ Note: SLJIT is designed to be independent from them as possible.
+
+ In release mode (SLJIT_DEBUG is not defined) only the following macros are needed:
+*/
+
+#ifndef SLJIT_MALLOC
+#define SLJIT_MALLOC(size) malloc(size)
+#endif
+
+#ifndef SLJIT_FREE
+#define SLJIT_FREE(ptr) free(ptr)
+#endif
+
+#ifndef SLJIT_MEMMOVE
+#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
+#endif
+
+#ifndef SLJIT_ZEROMEM
+#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
+#endif
+
+#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
+
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define SLJIT_LIKELY(x) __builtin_expect((x), 1)
+#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0)
+#else
+#define SLJIT_LIKELY(x) (x)
+#define SLJIT_UNLIKELY(x) (x)
+#endif
+
+#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
+
+#ifndef SLJIT_INLINE
+/* Inline functions. */
+#define SLJIT_INLINE __inline
+#endif
+
+#ifndef SLJIT_CONST
+/* Const variables. */
+#define SLJIT_CONST const
+#endif
+
+#ifndef SLJIT_UNUSED_ARG
+/* Unused arguments. */
+#define SLJIT_UNUSED_ARG(arg) (void)arg
+#endif
+
+#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
+/* Static ABI functions. For all-in-one programs. */
+
+#if defined(__GNUC__)
+/* Disable unused warnings in gcc. */
+#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE static
+#endif
+
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE
+#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
+
+#ifndef SLJIT_CACHE_FLUSH
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+
+/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ ppc_cache_flush((from), (to))
+
+#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+/* Not required to implement on archs with unified caches. */
+#define SLJIT_CACHE_FLUSH(from, to)
+
+#else
+
+/* Calls __ARM_NR_cacheflush on ARM-Linux. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ __clear_cache((char*)(from), (char*)(to))
+
+#endif
+
+#endif /* !SLJIT_CACHE_FLUSH */
+
+/* 8 bit byte type. */
+typedef unsigned char sljit_ub;
+typedef signed char sljit_b;
+
+/* 16 bit half-word type. */
+typedef unsigned short int sljit_uh;
+typedef signed short int sljit_h;
+
+/* 32 bit integer type. */
+typedef unsigned int sljit_ui;
+typedef signed int sljit_i;
+
+/* Machine word type. Can encapsulate a pointer.
+ 32 bit for 32 bit machines.
+ 64 bit for 64 bit machines. */
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+/* Just to have something. */
+#define SLJIT_WORD_SHIFT 0
+typedef unsigned long int sljit_uw;
+typedef long int sljit_w;
+#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_32BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 2
+typedef unsigned int sljit_uw;
+typedef int sljit_w;
+#else
+#define SLJIT_64BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 3
+#ifdef _WIN32
+typedef unsigned __int64 sljit_uw;
+typedef __int64 sljit_w;
+#else
+typedef unsigned long int sljit_uw;
+typedef long int sljit_w;
+#endif
+#endif
+
+/* Double precision. */
+#define SLJIT_FLOAT_SHIFT 3
+
+#ifndef SLJIT_W
+
+/* Defining long constants. */
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_W(w) (w##ll)
+#else
+#define SLJIT_W(w) (w)
+#endif
+
+#endif /* !SLJIT_W */
+
+#ifndef SLJIT_CALL
+
+/* ABI (Application Binary Interface) types. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+#if defined(__GNUC__)
+
+#define SLJIT_CALL __attribute__ ((fastcall))
+#define SLJIT_X86_32_FASTCALL 1
+
+#elif defined(_WIN32)
+
+#ifdef __BORLANDC__
+#define SLJIT_CALL __msfastcall
+#else /* __BORLANDC__ */
+#define SLJIT_CALL __fastcall
+#endif /* __BORLANDC__ */
+#define SLJIT_X86_32_FASTCALL 1
+
+#else /* defined(_WIN32) */
+#define SLJIT_CALL __stdcall
+#endif
+
+#else /* Other architectures. */
+
+#define SLJIT_CALL
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#endif /* !SLJIT_CALL */
+
+#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
+
+/* These macros are useful for the application. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_BIG_ENDIAN 1
+
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+
+#ifdef __MIPSEL__
+#define SLJIT_LITTLE_ENDIAN 1
+#else
+#define SLJIT_BIG_ENDIAN 1
+#endif
+
+#else
+#define SLJIT_LITTLE_ENDIAN 1
+#endif
+
+#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */
+
+/* Sanity check. */
+#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+/* It seems ppc64 compilers use an indirect addressing for functions.
+ It makes things really complicated. */
+#define SLJIT_INDIRECT_CALL 1
+#endif
+
+#ifndef SLJIT_SSE2
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+/* Turn on SSE2 support on x86 (operating on doubles).
+ (Better performance than legacy fpu instructions). */
+#define SLJIT_SSE2 1
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+/* Auto detect SSE2 support using CPUID.
+ On 64 bit x86 cpus, sse2 must be present. */
+#define SLJIT_SSE2_AUTO 1
+#endif
+
+#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */
+
+#endif /* !SLJIT_SSE2 */
+
+#ifndef SLJIT_UNALIGNED
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_UNALIGNED 1
+#endif
+
+#endif /* !SLJIT_UNALIGNED */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
+#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
+#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+#include <stdio.h>
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+
+/* Feel free to redefine these two macros. */
+#ifndef SLJIT_ASSERT
+
+#define SLJIT_HALT_PROCESS() \
+ *((int*)0) = 0
+
+#define SLJIT_ASSERT(x) \
+ do { \
+ if (SLJIT_UNLIKELY(!(x))) { \
+ printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT */
+
+#ifndef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT_STOP() \
+ do { \
+ printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT_STOP */
+
+#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+#undef SLJIT_ASSERT
+#undef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT(x) \
+ do { } while (0)
+#define SLJIT_ASSERT_STOP() \
+ do { } while (0)
+
+#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+#ifndef SLJIT_COMPILE_ASSERT
+
+/* Should be improved eventually. */
+#define SLJIT_COMPILE_ASSERT(x, description) \
+ SLJIT_ASSERT(x)
+
+#endif /* !SLJIT_COMPILE_ASSERT */
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitExecAllocator.c b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
new file mode 100644
index 0000000000..f66744df82
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
@@ -0,0 +1,277 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ This file contains a simple executable memory allocator
+
+ It is assumed, that executable code blocks are usually medium (or sometimes
+ large) memory blocks, and the allocator is not too frequently called (less
+ optimized than other allocators). Thus, using it as a generic allocator is
+ not suggested.
+
+ How does it work:
+ Memory is allocated in continuous memory areas called chunks by alloc_chunk()
+ Chunk format:
+ [ block ][ block ] ... [ block ][ block terminator ]
+
+ All blocks and the block terminator is started with block_header. The block
+ header contains the size of the previous and the next block. These sizes
+ can also contain special values.
+ Block size:
+ 0 - The block is a free_block, with a different size member.
+ 1 - The block is a block terminator.
+ n - The block is used at the moment, and the value contains its size.
+ Previous block size:
+ 0 - This is the first block of the memory chunk.
+ n - The size of the previous block.
+
+ Using these size values we can go forward or backward on the block chain.
+ The unused blocks are stored in a chain list pointed by free_blocks. This
+ list is useful if we need to find a suitable memory area when the allocator
+ is called.
+
+ When a block is freed, the new free block is connected to its adjacent free
+ blocks if possible.
+
+ [ free block ][ used block ][ free block ]
+ and "used block" is freed, the three blocks are connected together:
+ [ one big free block ]
+*/
+
+/* --------------------------------------------------------------------- */
+/* System (OS) functions */
+/* --------------------------------------------------------------------- */
+
+/* 64 KByte. */
+#define CHUNK_SIZE 0x10000
+
+/*
+ alloc_chunk / free_chunk :
+ * allocate executable system memory chunks
+ * the size is always divisible by CHUNK_SIZE
+ allocator_grab_lock / allocator_release_lock :
+ * make the allocator thread safe
+ * can be empty if the OS (or the application) does not support threading
+ * only the allocator requires this lock, sljit is fully thread safe
+ as it only uses local variables
+*/
+
+#ifdef _WIN32
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+}
+
+static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+{
+ SLJIT_UNUSED_ARG(size);
+ VirtualFree(chunk, 0, MEM_RELEASE);
+}
+
+#else
+
+#include <sys/mman.h>
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
+ return (retval != MAP_FAILED) ? retval : NULL;
+}
+
+static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+{
+ munmap(chunk, size);
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Common functions */
+/* --------------------------------------------------------------------- */
+
+#define CHUNK_MASK (~(CHUNK_SIZE - 1))
+
+struct block_header {
+ sljit_uw size;
+ sljit_uw prev_size;
+};
+
+struct free_block {
+ struct block_header header;
+ struct free_block *next;
+ struct free_block *prev;
+ sljit_uw size;
+};
+
+#define AS_BLOCK_HEADER(base, offset) \
+ ((struct block_header*)(((sljit_ub*)base) + offset))
+#define AS_FREE_BLOCK(base, offset) \
+ ((struct free_block*)(((sljit_ub*)base) + offset))
+#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header)))
+#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
+
+static struct free_block* free_blocks;
+static sljit_uw allocated_size;
+static sljit_uw total_size;
+
+static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
+{
+ free_block->header.size = 0;
+ free_block->size = size;
+
+ free_block->next = free_blocks;
+ free_block->prev = 0;
+ if (free_blocks)
+ free_blocks->prev = free_block;
+ free_blocks = free_block;
+}
+
+static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
+{
+ if (free_block->next)
+ free_block->next->prev = free_block->prev;
+
+ if (free_block->prev)
+ free_block->prev->next = free_block->next;
+ else {
+ SLJIT_ASSERT(free_blocks == free_block);
+ free_blocks = free_block->next;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+ struct block_header *header;
+ struct block_header *next_header;
+ struct free_block *free_block;
+ sljit_uw chunk_size;
+
+ allocator_grab_lock();
+ if (size < sizeof(struct free_block))
+ size = sizeof(struct free_block);
+ size = ALIGN_SIZE(size);
+
+ free_block = free_blocks;
+ while (free_block) {
+ if (free_block->size >= size) {
+ chunk_size = free_block->size;
+ if (chunk_size > size + 64) {
+ /* We just cut a block from the end of the free block. */
+ chunk_size -= size;
+ free_block->size = chunk_size;
+ header = AS_BLOCK_HEADER(free_block, chunk_size);
+ header->prev_size = chunk_size;
+ AS_BLOCK_HEADER(header, size)->prev_size = size;
+ }
+ else {
+ sljit_remove_free_block(free_block);
+ header = (struct block_header*)free_block;
+ size = chunk_size;
+ }
+ allocated_size += size;
+ header->size = size;
+ allocator_release_lock();
+ return MEM_START(header);
+ }
+ free_block = free_block->next;
+ }
+
+ chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
+ header = (struct block_header*)alloc_chunk(chunk_size);
+ PTR_FAIL_IF(!header);
+
+ chunk_size -= sizeof(struct block_header);
+ total_size += chunk_size;
+
+ header->prev_size = 0;
+ if (chunk_size > size + 64) {
+ /* Cut the allocated space into a free and a used block. */
+ allocated_size += size;
+ header->size = size;
+ chunk_size -= size;
+
+ free_block = AS_FREE_BLOCK(header, size);
+ free_block->header.prev_size = size;
+ sljit_insert_free_block(free_block, chunk_size);
+ next_header = AS_BLOCK_HEADER(free_block, chunk_size);
+ }
+ else {
+ /* All space belongs to this allocation. */
+ allocated_size += chunk_size;
+ header->size = chunk_size;
+ next_header = AS_BLOCK_HEADER(header, chunk_size);
+ }
+ next_header->size = 1;
+ next_header->prev_size = chunk_size;
+ allocator_release_lock();
+ return MEM_START(header);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ struct block_header *header;
+ struct free_block* free_block;
+
+ allocator_grab_lock();
+ header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header));
+ allocated_size -= header->size;
+
+ /* Connecting free blocks together if possible. */
+
+ /* If header->prev_size == 0, free_block will equal to header.
+ In this case, free_block->header.size will be > 0. */
+ free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size);
+ if (SLJIT_UNLIKELY(!free_block->header.size)) {
+ free_block->size += header->size;
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+ else {
+ free_block = (struct free_block*)header;
+ sljit_insert_free_block(free_block, header->size);
+ }
+
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ if (SLJIT_UNLIKELY(!header->size)) {
+ free_block->size += ((struct free_block*)header)->size;
+ sljit_remove_free_block((struct free_block*)header);
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+
+ /* The whole chunk is free. */
+ if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
+ /* If this block is freed, we still have (allocated_size / 2) free space. */
+ if (total_size - free_block->size > (allocated_size * 3 / 2)) {
+ total_size -= free_block->size;
+ sljit_remove_free_block(free_block);
+ free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ }
+ }
+
+ allocator_release_lock();
+}
diff --git a/src/3rdparty/pcre/sljit/sljitLir.c b/src/3rdparty/pcre/sljit/sljitLir.c
new file mode 100644
index 0000000000..c1fa5e4af9
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitLir.c
@@ -0,0 +1,1594 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sljitLir.h"
+
+#define CHECK_ERROR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return compiler->error; \
+ } while (0)
+
+#define CHECK_ERROR_PTR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return NULL; \
+ } while (0)
+
+#define CHECK_ERROR_VOID() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return; \
+ } while (0)
+
+#define FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return compiler->error; \
+ } while (0)
+
+#define PTR_FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return NULL; \
+ } while (0)
+
+#define FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return SLJIT_ERR_ALLOC_FAILED; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_WITH_EXEC_IF(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#define GET_OPCODE(op) \
+ ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define GET_FLAGS(op) \
+ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))
+
+#define GET_ALL_FLAGS(op) \
+ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define BUF_SIZE 4096
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define ABUF_SIZE 2048
+#else
+#define ABUF_SIZE 4096
+#endif
+
+/* Jump flags. */
+#define JUMP_LABEL 0x1
+#define JUMP_ADDR 0x2
+/* SLJIT_REWRITABLE_JUMP is 0x1000. */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #define PATCH_MB 0x4
+ #define PATCH_MW 0x8
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #define PATCH_MD 0x10
+#endif
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ #define IS_BL 0x4
+ #define PATCH_B 0x8
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ #define CPOOL_SIZE 512
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ #define IS_CONDITIONAL 0x04
+ #define IS_BL 0x08
+ /* cannot be encoded as branch */
+ #define B_TYPE0 0x00
+ /* conditional + imm8 */
+ #define B_TYPE1 0x10
+ /* conditional + imm20 */
+ #define B_TYPE2 0x20
+ /* IT + imm24 */
+ #define B_TYPE3 0x30
+ /* imm11 */
+ #define B_TYPE4 0x40
+ /* imm24 */
+ #define B_TYPE5 0x50
+ /* BL + imm24 */
+ #define BL_TYPE6 0x60
+ /* 0xf00 cc code for branches */
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ #define UNCOND_B 0x04
+ #define PATCH_B 0x08
+ #define ABSOLUTE_B 0x10
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define IS_MOVABLE 0x04
+ #define IS_JAL 0x08
+ #define IS_BIT26_COND 0x10
+ #define IS_BIT16_COND 0x20
+
+ #define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
+
+ #define PATCH_B 0x40
+ #define PATCH_J 0x80
+
+ /* instruction types */
+ #define UNMOVABLE_INS 0
+ /* 1 - 31 last destination register */
+ #define FCSR_FCC 32
+ /* no destination (i.e: store) */
+ #define MOVABLE_INS 33
+#endif
+
+#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
+
+/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
+#include "sljitUtils.c"
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+#include "sljitExecAllocator.c"
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2)
+#error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Public functions */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)))
+#define SLJIT_NEEDS_COMPILER_INIT 1
+static int compiler_initialized = 0;
+/* A thread safe initialization. */
+static void init_compiler(void);
+#endif
+
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+{
+ struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler));
+ if (!compiler)
+ return NULL;
+ SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
+
+ SLJIT_COMPILE_ASSERT(
+ sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1
+ && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2
+ && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4
+ && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)),
+ invalid_integer_types);
+
+ /* Only the non-zero members must be set. */
+ compiler->error = SLJIT_SUCCESS;
+
+ compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
+ compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
+
+ if (!compiler->buf || !compiler->abuf) {
+ if (compiler->buf)
+ SLJIT_FREE(compiler->buf);
+ if (compiler->abuf)
+ SLJIT_FREE(compiler->abuf);
+ SLJIT_FREE(compiler);
+ return NULL;
+ }
+
+ compiler->buf->next = NULL;
+ compiler->buf->used_size = 0;
+ compiler->abuf->next = NULL;
+ compiler->abuf->used_size = 0;
+
+ compiler->temporaries = -1;
+ compiler->saveds = -1;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->args = -1;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub));
+ if (!compiler->cpool) {
+ SLJIT_FREE(compiler->buf);
+ SLJIT_FREE(compiler->abuf);
+ SLJIT_FREE(compiler);
+ return NULL;
+ }
+ compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE);
+ compiler->cpool_diff = 0xffffffff;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ compiler->delay_slot = UNMOVABLE_INS;
+#endif
+
+#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
+ if (!compiler_initialized) {
+ init_compiler();
+ compiler_initialized = 1;
+ }
+#endif
+
+ return compiler;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *curr;
+
+ buf = compiler->buf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr);
+ }
+
+ buf = compiler->abuf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr);
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_FREE(compiler->cpool);
+#endif
+ SLJIT_FREE(compiler);
+}
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Remove thumb mode flag. */
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
+}
+#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Resolve indirection. */
+ code = (void*)(*(sljit_uw*)code);
+ SLJIT_FREE_EXEC(code);
+}
+#else
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_FREE_EXEC(code);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
+ jump->flags &= ~JUMP_ADDR;
+ jump->flags |= JUMP_LABEL;
+ jump->u.label = label;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ if (SLJIT_LIKELY(!!jump)) {
+ SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP);
+
+ jump->flags &= ~JUMP_LABEL;
+ jump->flags |= JUMP_ADDR;
+ jump->u.target = target;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Private functions */
+/* --------------------------------------------------------------------- */
+
+static void* ensure_buf(struct sljit_compiler *compiler, int size)
+{
+ sljit_ub *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
+ ret = compiler->buf->memory + compiler->buf->used_size;
+ compiler->buf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->buf;
+ compiler->buf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+static void* ensure_abuf(struct sljit_compiler *compiler, int size)
+{
+ sljit_ub *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
+ ret = compiler->abuf->memory + compiler->abuf->used_size;
+ compiler->abuf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->abuf;
+ compiler->abuf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
+{
+ CHECK_ERROR_PTR();
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ if (size <= 0 || size > 128)
+ return NULL;
+ size = (size + 7) & ~7;
+#else
+ if (size <= 0 || size > 64)
+ return NULL;
+ size = (size + 3) & ~3;
+#endif
+ return ensure_abuf(compiler, size);
+}
+
+static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf = compiler->buf;
+ struct sljit_memory_fragment *prev = NULL;
+ struct sljit_memory_fragment *tmp;
+
+ do {
+ tmp = buf->next;
+ buf->next = prev;
+ prev = buf;
+ buf = tmp;
+ } while (buf != NULL);
+
+ compiler->buf = prev;
+}
+
+static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
+{
+ label->next = NULL;
+ label->size = compiler->size;
+ if (compiler->last_label)
+ compiler->last_label->next = label;
+ else
+ compiler->labels = label;
+ compiler->last_label = label;
+}
+
+static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags)
+{
+ jump->next = NULL;
+ jump->flags = flags;
+ if (compiler->last_jump)
+ compiler->last_jump->next = jump;
+ else
+ compiler->jumps = jump;
+ compiler->last_jump = jump;
+}
+
+static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
+{
+ const_->next = NULL;
+ const_->addr = compiler->size;
+ if (compiler->last_const)
+ compiler->last_const->next = const_;
+ else
+ compiler->consts = const_;
+ compiler->last_const = const_;
+}
+
+#define ADDRESSING_DEPENDS_ON(exp, reg) \
+ (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg))
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+#define FUNCTION_CHECK_OP() \
+ SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
+ switch (GET_OPCODE(op)) { \
+ case SLJIT_NOT: \
+ case SLJIT_CLZ: \
+ case SLJIT_AND: \
+ case SLJIT_OR: \
+ case SLJIT_XOR: \
+ case SLJIT_SHL: \
+ case SLJIT_LSHR: \
+ case SLJIT_ASHR: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_NEG: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_MUL: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_FCMP: \
+ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
+ break; \
+ case SLJIT_ADD: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \
+ break; \
+ case SLJIT_SUB: \
+ break; \
+ case SLJIT_ADDC: \
+ case SLJIT_SUBC: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \
+ break; \
+ default: \
+ /* Nothing allowed */ \
+ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ break; \
+ }
+
+#define FUNCTION_CHECK_IS_REG(r) \
+ ((r) == SLJIT_UNUSED || (r) == SLJIT_LOCALS_REG || \
+ ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG3 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG3 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) \
+
+#define FUNCTION_CHECK_SRC(p, i) \
+ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \
+ if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((p) >= SLJIT_SAVED_REG1 && (p) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds) || \
+ (p) == SLJIT_LOCALS_REG) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) == SLJIT_IMM) \
+ ; \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_CHECK_DST(p, i) \
+ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \
+ if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((p) >= SLJIT_SAVED_REG1 && (p) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds) || \
+ (p) == SLJIT_UNUSED) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_FCHECK(p, i) \
+ if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_CHECK_OP1() \
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
+ SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \
+ } \
+ if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
+ SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \
+ SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \
+ if ((src & SLJIT_MEM) && (src & 0xf)) \
+ SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \
+ }
+
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ compiler->verbose = verbose;
+}
+
+static char* reg_names[] = {
+ (char*)"<noreg>", (char*)"t1", (char*)"t2", (char*)"t3",
+ (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2",
+ (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr"
+};
+
+static char* freg_names[] = {
+ (char*)"<noreg>", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4"
+};
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#ifdef _WIN64
+ #define SLJIT_PRINT_D "I64"
+#else
+ #define SLJIT_PRINT_D "l"
+#endif
+#else
+ #define SLJIT_PRINT_D ""
+#endif
+
+#define sljit_verbose_param(p, i) \
+ if ((p) & SLJIT_IMM) \
+ fprintf(compiler->verbose, "#%"SLJIT_PRINT_D"d", (i)); \
+ else if ((p) & SLJIT_MEM) { \
+ if ((p) & 0xf) { \
+ if (i) { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
+ else \
+ fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
+ } \
+ else { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
+ else \
+ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
+ } \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
+ } else \
+ fprintf(compiler->verbose, "%s", reg_names[p]);
+#define sljit_verbose_fparam(p, i) \
+ if ((p) & SLJIT_MEM) { \
+ if ((p) & 0xf) { \
+ if (i) { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
+ else \
+ fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
+ } \
+ else { \
+ if (((p) >> 4) & 0xF) \
+ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
+ else \
+ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
+ } \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
+ } else \
+ fprintf(compiler->verbose, "%s", freg_names[p]);
+
+static SLJIT_CONST char* op_names[] = {
+ /* op0 */
+ (char*)"breakpoint", (char*)"nop",
+ (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv",
+ /* op1 */
+ (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh",
+ (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu",
+ (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh",
+ (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg",
+ (char*)"clz",
+ /* op2 */
+ (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
+ (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
+ (char*)"shl", (char*)"lshr", (char*)"ashr",
+ /* fop1 */
+ (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs",
+ /* fop2 */
+ (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv"
+};
+
+static char* jump_names[] = {
+ (char*)"c_equal", (char*)"c_not_equal",
+ (char*)"c_less", (char*)"c_greater_equal",
+ (char*)"c_greater", (char*)"c_less_equal",
+ (char*)"c_sig_less", (char*)"c_sig_greater_equal",
+ (char*)"c_sig_greater", (char*)"c_sig_less_equal",
+ (char*)"c_overflow", (char*)"c_not_overflow",
+ (char*)"c_mul_overflow", (char*)"c_mul_not_overflow",
+ (char*)"c_float_equal", (char*)"c_float_not_equal",
+ (char*)"c_float_less", (char*)"c_float_greater_equal",
+ (char*)"c_float_greater", (char*)"c_float_less_equal",
+ (char*)"c_float_nan", (char*)"c_float_not_nan",
+ (char*)"jump", (char*)"fast_call",
+ (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
+};
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Arch dependent */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler)
+{
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ struct sljit_jump *jump;
+#endif
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+
+ SLJIT_ASSERT(compiler->size > 0);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ jump = compiler->jumps;
+ while (jump) {
+ /* All jumps have target. */
+ SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
+ jump = jump->next;
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " fake_enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (op != SLJIT_UNUSED) {
+ SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_SI);
+ FUNCTION_CHECK_SRC(src, srcw);
+ }
+ else
+ SLJIT_ASSERT(src == 0 && srcw == 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (op == SLJIT_UNUSED)
+ fprintf(compiler->verbose, " return\n");
+ else {
+ fprintf(compiler->verbose, " return %s ", op_names[op]);
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ FUNCTION_CHECK_DST(dst, dstw);
+ compiler->temporaries = -1;
+ compiler->saveds = -1;
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_enter ");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, " args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_return ");
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+
+ SLJIT_ASSERT((op >= SLJIT_BREAKPOINT && op <= SLJIT_SMUL)
+ || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src, srcw);
+ FUNCTION_CHECK_DST(dst, dstw);
+ FUNCTION_CHECK_OP1();
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_get_register_index(int reg)
+{
+ SLJIT_UNUSED_ARG(reg);
+ SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS);
+}
+
+static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(instruction);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT(instruction);
+}
+
+static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_FCHECK(src, srcw);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S");
+ sljit_verbose_fparam(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]);
+ sljit_verbose_fparam(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, "label:\n");
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+ sljit_verbose_param(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_NOT_NAN);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fcmp%s <%s> ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+ sljit_verbose_fparam(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]);
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(type);
+
+ SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP);
+ SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR);
+ SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E",
+ !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]);
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(init_value);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " const ");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", #%"SLJIT_PRINT_D"d\n", init_value);
+ }
+#endif
+}
+
+static SLJIT_INLINE int emit_mov_before_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ /* Return if don't need to do anything. */
+ if (op == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ if (src == SLJIT_RETURN_REG && op == SLJIT_MOV)
+ return SLJIT_SUCCESS;
+#else
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI))
+ return SLJIT_SUCCESS;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
+}
+
+/* CPU description section */
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 32bit ("
+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 64bit ("
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "little endian + "
+#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "big endian + "
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
+#define SLJIT_CPUINFO_PART3 "unaligned)"
+#else
+#define SLJIT_CPUINFO_PART3 "aligned)"
+#endif
+
+#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ #include "sljitNativeX86_common.c"
+#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #include "sljitNativeX86_common.c"
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ #include "sljitNativeARM_v5.c"
+#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ #include "sljitNativeARM_v5.c"
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ #include "sljitNativeARM_Thumb2.c"
+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ #include "sljitNativePPC_common.c"
+#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ #include "sljitNativePPC_common.c"
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #include "sljitNativeMIPS_common.c"
+#endif
+
+#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* Default compare for most architectures. */
+ int flags, tmp_src, condition;
+ sljit_w tmp_srcw;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
+
+ condition = type & 0xff;
+ if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
+ /* Immediate is prefered as second argument by most architectures. */
+ switch (condition) {
+ case SLJIT_C_LESS:
+ condition = SLJIT_C_GREATER;
+ break;
+ case SLJIT_C_GREATER_EQUAL:
+ condition = SLJIT_C_LESS_EQUAL;
+ break;
+ case SLJIT_C_GREATER:
+ condition = SLJIT_C_LESS;
+ break;
+ case SLJIT_C_LESS_EQUAL:
+ condition = SLJIT_C_GREATER_EQUAL;
+ break;
+ case SLJIT_C_SIG_LESS:
+ condition = SLJIT_C_SIG_GREATER;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ condition = SLJIT_C_SIG_LESS_EQUAL;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ condition = SLJIT_C_SIG_LESS;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ condition = SLJIT_C_SIG_GREATER_EQUAL;
+ break;
+ }
+ type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP));
+ tmp_src = src1;
+ src1 = src2;
+ src2 = tmp_src;
+ tmp_srcw = src1w;
+ src1w = src2w;
+ src2w = tmp_srcw;
+ }
+
+ if (condition <= SLJIT_C_NOT_ZERO)
+ flags = SLJIT_SET_E;
+ else if (condition <= SLJIT_C_LESS_EQUAL)
+ flags = SLJIT_SET_U;
+ else
+ flags = SLJIT_SET_S;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP),
+ SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int flags, condition;
+
+ check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
+
+ condition = type & 0xff;
+ if (condition <= SLJIT_C_FLOAT_NOT_EQUAL)
+ flags = SLJIT_SET_E;
+ else
+ flags = SLJIT_SET_S;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ sljit_emit_fop1(compiler, SLJIT_FCMP | flags, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+#endif
+
+#else /* SLJIT_CONFIG_UNSUPPORTED */
+
+/* Empty function bodies for those machines, which are not (yet) supported. */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "unsupported";
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+{
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(verbose);
+ SLJIT_ASSERT_STOP();
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_UNUSED_ARG(code);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ SLJIT_ASSERT_STOP();
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(instruction);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ SLJIT_ASSERT_STOP();
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(label);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(target);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(initval);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_addr);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_constant);
+ SLJIT_ASSERT_STOP();
+}
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitLir.h b/src/3rdparty/pcre/sljit/sljitLir.h
new file mode 100644
index 0000000000..0cb1c1e589
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitLir.h
@@ -0,0 +1,853 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_LIR_H_
+#define _SLJIT_LIR_H_
+
+/*
+ ------------------------------------------------------------------------
+ Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
+ ------------------------------------------------------------------------
+
+ Short description
+ Advantages:
+ - The execution can be continued from any LIR instruction
+ In other words, jump into and out of the code is safe
+ - Both target of (conditional) jump and call instructions
+ and constants can be dynamically modified during runtime
+ - although it is not suggested to do it frequently
+ - very effective to cache an important value once
+ - A fixed stack space can be allocated for local variables
+ - The compiler is thread-safe
+ Disadvantages:
+ - Limited number of registers (only 6+4 integer registers, max 3+2
+ temporary, max 3+2 saved and 4 floating point registers)
+ In practice:
+ - This approach is very effective for interpreters
+ - One of the saved registers typically points to a stack interface
+ - It can jump to any exception handler anytime (even for another
+ function. It is safe for SLJIT.)
+ - Fast paths can be modified during runtime reflecting the changes
+ of the fastest execution path of the dynamic language
+ - SLJIT supports complex memory addressing modes
+ - mainly position independent code
+ - Optimizations (perhaps later)
+ - Only for basic blocks (when no labels inserted between LIR instructions)
+
+ For valgrind users:
+ - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
+*/
+
+#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
+#include "sljitConfig.h"
+#endif
+
+/* The following header file defines useful macros for fine tuning
+sljit based code generators. They are listed in the begining
+of sljitConfigInternal.h */
+
+#include "sljitConfigInternal.h"
+
+/* --------------------------------------------------------------------- */
+/* Error codes */
+/* --------------------------------------------------------------------- */
+
+/* Indicates no error. */
+#define SLJIT_SUCCESS 0
+/* After the call of sljit_generate_code(), the error code of the compiler
+ is set to this value to avoid future sljit calls (in debug mode at least).
+ The complier should be freed after sljit_generate_code(). */
+#define SLJIT_ERR_COMPILED 1
+/* Cannot allocate non executable memory. */
+#define SLJIT_ERR_ALLOC_FAILED 2
+/* Cannot allocate executable memory.
+ Only for sljit_generate_code() */
+#define SLJIT_ERR_EX_ALLOC_FAILED 3
+/* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */
+#define SLJIT_ERR_UNSUPPORTED 4
+
+/* --------------------------------------------------------------------- */
+/* Registers */
+/* --------------------------------------------------------------------- */
+
+#define SLJIT_UNUSED 0
+
+/* Temporary (scratch) registers may not preserve their values across function calls. */
+#define SLJIT_TEMPORARY_REG1 1
+#define SLJIT_TEMPORARY_REG2 2
+#define SLJIT_TEMPORARY_REG3 3
+/* Note: Extra Registers cannot be used for memory addressing. */
+/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
+#define SLJIT_TEMPORARY_EREG1 4
+#define SLJIT_TEMPORARY_EREG2 5
+
+/* Saved registers whose preserve their values across function calls. */
+#define SLJIT_SAVED_REG1 6
+#define SLJIT_SAVED_REG2 7
+#define SLJIT_SAVED_REG3 8
+/* Note: Extra Registers cannot be used for memory addressing. */
+/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
+#define SLJIT_SAVED_EREG1 9
+#define SLJIT_SAVED_EREG2 10
+
+/* Read-only register (cannot be the destination of an operation). */
+/* Note: SLJIT_MEM2( ... , SLJIT_LOCALS_REG) is not supported (x86 limitation). */
+/* Note: SLJIT_LOCALS_REG is not necessary the real stack pointer. See sljit_emit_enter. */
+#define SLJIT_LOCALS_REG 11
+
+/* Number of registers. */
+#define SLJIT_NO_TMP_REGISTERS 5
+#define SLJIT_NO_GEN_REGISTERS 5
+#define SLJIT_NO_REGISTERS 11
+
+/* Return with machine word. */
+
+#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1
+
+/* x86 prefers specific registers for special purposes. In case of shift
+ by register it supports only SLJIT_TEMPORARY_REG3 for shift argument
+ (which is the src2 argument of sljit_emit_op2). If another register is
+ used, sljit must exchange data between registers which cause a minor
+ slowdown. Other architectures has no such limitation. */
+
+#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3
+
+/* --------------------------------------------------------------------- */
+/* Floating point registers */
+/* --------------------------------------------------------------------- */
+
+/* Note: SLJIT_UNUSED as destination is not valid for floating point
+ operations, since they cannot be used for setting flags. */
+
+/* Floating point operations are performed on double precision values. */
+
+#define SLJIT_FLOAT_REG1 1
+#define SLJIT_FLOAT_REG2 2
+#define SLJIT_FLOAT_REG3 3
+#define SLJIT_FLOAT_REG4 4
+
+/* --------------------------------------------------------------------- */
+/* Main structures and functions */
+/* --------------------------------------------------------------------- */
+
+struct sljit_memory_fragment {
+ struct sljit_memory_fragment *next;
+ sljit_uw used_size;
+ sljit_ub memory[1];
+};
+
+struct sljit_label {
+ struct sljit_label *next;
+ sljit_uw addr;
+ /* The maximum size difference. */
+ sljit_uw size;
+};
+
+struct sljit_jump {
+ struct sljit_jump *next;
+ sljit_uw addr;
+ sljit_w flags;
+ union {
+ sljit_uw target;
+ struct sljit_label* label;
+ } u;
+};
+
+struct sljit_const {
+ struct sljit_const *next;
+ sljit_uw addr;
+};
+
+struct sljit_compiler {
+ int error;
+
+ struct sljit_label *labels;
+ struct sljit_jump *jumps;
+ struct sljit_const *consts;
+ struct sljit_label *last_label;
+ struct sljit_jump *last_jump;
+ struct sljit_const *last_const;
+
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *abuf;
+
+ /* Used local registers. */
+ int temporaries;
+ /* Used saved registers. */
+ int saveds;
+ /* Local stack size. */
+ int local_size;
+ /* Code size. */
+ sljit_uw size;
+ /* For statistical purposes. */
+ sljit_uw executable_size;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int args;
+ int temporaries_start;
+ int saveds_start;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int mode32;
+#ifdef _WIN64
+ int has_locals;
+#endif
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int flags_saved;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Constant pool handling. */
+ sljit_uw *cpool;
+ sljit_ub *cpool_unique;
+ sljit_uw cpool_diff;
+ sljit_uw cpool_fill;
+ /* Other members. */
+ /* Contains pointer, "ldr pc, [...]" pairs. */
+ sljit_uw patches;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ /* Temporary fields. */
+ sljit_uw shift_imm;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ int has_locals;
+ sljit_w imm;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ int has_locals;
+ int delay_slot;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ FILE* verbose;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ int skip_checks;
+#endif
+};
+
+/* --------------------------------------------------------------------- */
+/* Main functions */
+/* --------------------------------------------------------------------- */
+
+/* Creates an sljit compiler.
+ Returns NULL if failed. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
+/* Free everything except the codes. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
+
+static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
+
+/*
+ Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
+ and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler,
+ and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned.
+ Excellent for allocating small blocks during the compiling, and no need to worry
+ about freeing them. The size is enough to contain at most 16 pointers.
+ If the size is outside of the range, the function will return with NULL,
+ but this return value does not indicate that there is no more memory (does
+ not set the compiler to out-of-memory status).
+*/
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+/* Passing NULL disables verbose. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
+
+/*
+ After the code generation we can retrieve the allocated executable memory size,
+ although this area may not be fully filled with instructions depending on some
+ optimizations. This function is useful only for statistical purposes.
+
+ Before a successful code generation, this function returns with 0.
+*/
+static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
+
+/* Instruction generation. Returns with error code. */
+
+/*
+ The executable code is basically a function call from the viewpoint of
+ the C language. The function calls must obey to the ABI (Application
+ Binary Interface) of the platform, which specify the purpose of machine
+ registers and stack handling among other things. The sljit_emit_enter
+ function emits the necessary instructions for setting up a new context
+ for the executable code and moves function arguments to the saved
+ registers. The number of arguments are specified in the "args"
+ parameter and the first argument goes to SLJIT_SAVED_REG1, the second
+ goes to SLJIT_SAVED_REG2 and so on. The number of temporary and
+ saved registers are passed in "temporaries" and "saveds" arguments
+ respectively. Since the saved registers contains the arguments,
+ "args" must be less or equal than "saveds". The sljit_emit_enter
+ is also capable of allocating a stack space for local variables. The
+ "local_size" argument contains the size in bytes of this local area
+ and its staring address is stored in SLJIT_LOCALS_REG. However
+ the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
+ The memory bytes between SLJIT_LOCALS_REG (inclusive) and
+ SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
+ until the function returns. The stack space is uninitialized.
+
+ Note: every call of sljit_emit_enter and sljit_set_context overwrites
+ the previous context. */
+
+#define SLJIT_MAX_LOCAL_SIZE 65536
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler,
+ int args, int temporaries, int saveds, int local_size);
+
+/* The machine code has a context (which contains the local stack space size,
+ number of used registers, etc.) which initialized by sljit_emit_enter. Several
+ functions (like sljit_emit_return) requres this context to be able to generate
+ the appropriate code. However, some code fragments (like inline cache) may have
+ no normal entry point so their context is unknown for the compiler. Using the
+ function below we can specify thir context.
+
+ Note: every call of sljit_emit_enter and sljit_set_context overwrites
+ the previous context. */
+
+/* Note: multiple calls of this function overwrites the previous call. */
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
+ int args, int temporaries, int saveds, int local_size);
+
+/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
+ function does not return with anything or any opcode between SLJIT_MOV and
+ SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op
+ is SLJIT_UNUSED, otherwise see below the description about source and
+ destination arguments. */
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op,
+ int src, sljit_w srcw);
+
+/* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL).
+ All registers and even the stack frame is passed to the callee. The return address is
+ preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can
+ use this as a return value later. */
+
+/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions
+ are needed. Excellent for small uility functions, where saving registers and setting up
+ a new stack frame would cost too much performance. However, it is still possible to return
+ to the address of the caller (or anywhere else). */
+
+/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
+
+/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
+ since many architectures do clever branch prediction on call / return instruction pairs. */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size);
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw);
+
+/*
+ Source and destination values for arithmetical instructions
+ imm - a simple immediate value (cannot be used as a destination)
+ reg - any of the registers (immediate argument must be 0)
+ [imm] - absolute immediate memory address
+ [reg+imm] - indirect memory address
+ [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
+ useful for (byte, half, int, sljit_w) array access
+ (fully supported by both x86 and ARM architectures, and cheap operation on others)
+*/
+
+/*
+ IMPORATNT NOTE: memory access MUST be naturally aligned except
+ SLJIT_UNALIGNED macro is defined and its value is 1.
+
+ length | alignment
+ ---------+-----------
+ byte | 1 byte (not aligned)
+ half | 2 byte (real_address & 0x1 == 0)
+ int | 4 byte (real_address & 0x3 == 0)
+ sljit_w | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
+ | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
+
+ Note: different architectures have different addressing limitations
+ Thus sljit may generate several instructions for other addressing modes
+ x86: all addressing modes supported, but write-back is not supported
+ (requires an extra instruction). On x86-64 only 32 bit signed
+ integers are supported by the architecture.
+ arm: [reg+imm] supported for small immediates (-4095 <= imm <= 4095
+ or -255 <= imm <= 255 for loading signed bytes, any halfs or doubles)
+ [reg+(reg<<imm)] are supported or requires only two instructions
+ Write back is limited to small immediates on thumb2
+ ppc: [reg+imm], -65535 <= imm <= 65535. 64 bit moves requires immediates
+ divisible by 4. [reg+reg] supported, write-back supported
+ [reg+(reg<<imm)] (imm != 0) is cheap (requires two instructions)
+*/
+
+/* Register output: simply the name of the register.
+ For destination, you can use SLJIT_UNUSED as well. */
+#define SLJIT_MEM 0x100
+#define SLJIT_MEM0() (SLJIT_MEM)
+#define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
+#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 4))
+#define SLJIT_IMM 0x200
+
+/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
+ 32 bit CPUs. The arithmetic instruction uses only the lower 32 bit of the
+ input register(s), and set the flags according to the 32 bit result. If the
+ destination is a register, the higher 32 bit of the result is undefined.
+ The addressing modes (SLJIT_MEM1/SLJIT_MEM2 macros) are unaffected by this flag. */
+#define SLJIT_INT_OP 0x100
+
+/* Common CPU status flags for all architectures (x86, ARM, PPC)
+ - carry flag
+ - overflow flag
+ - zero flag
+ - negative/positive flag (depends on arc)
+ On mips, these flags are emulated by software. */
+
+/* By default, the instructions may, or may not set the CPU status flags.
+ Forcing to set or keep status flags can be done with the following flags: */
+
+/* Note: sljit tries to emit the minimum number of instructions. Using these
+ flags can increase them, so use them wisely to avoid unnecessary code generation. */
+
+/* Set Equal (Zero) status flag (E). */
+#define SLJIT_SET_E 0x0200
+/* Set signed status flag (S). */
+#define SLJIT_SET_S 0x0400
+/* Set unsgined status flag (U). */
+#define SLJIT_SET_U 0x0800
+/* Set signed overflow flag (O). */
+#define SLJIT_SET_O 0x1000
+/* Set carry flag (C).
+ Note: Kinda unsigned overflow, but behaves differently on various cpus. */
+#define SLJIT_SET_C 0x2000
+/* Do not modify the flags (K).
+ Note: This flag cannot be combined with any other SLJIT_SET_* flag. */
+#define SLJIT_KEEP_FLAGS 0x4000
+
+/* Notes:
+ - you cannot postpone conditional jump instructions except if noted that
+ the instruction does not set flags (See: SLJIT_KEEP_FLAGS).
+ - flag combinations: '|' means 'logical or'. */
+
+/* Flags: - (never set any flags)
+ Note: breakpoint instruction is not supported by all architectures (namely ppc)
+ It falls back to SLJIT_NOP in those cases. */
+#define SLJIT_BREAKPOINT 0
+/* Flags: - (never set any flags)
+ Note: may or may not cause an extra cycle wait
+ it can even decrease the runtime in a few cases. */
+#define SLJIT_NOP 1
+/* Flags: may destroy flags
+ Unsigned multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.
+ Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */
+#define SLJIT_UMUL 2
+/* Flags: may destroy flags
+ Signed multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.
+ Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */
+#define SLJIT_SMUL 3
+/* Flags: I | may destroy flags
+ Unsigned divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2.
+ The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.
+ Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */
+#define SLJIT_UDIV 4
+/* Flags: I | may destroy flags
+ Signed divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2.
+ The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.
+ Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */
+#define SLJIT_SDIV 5
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op);
+
+/* Notes for MOV instructions:
+ U = Mov with update (post form). If source or destination defined as SLJIT_MEM1(r1)
+ or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
+ UB = unsigned byte (8 bit)
+ SB = signed byte (8 bit)
+ UH = unsgined half (16 bit)
+ SH = unsgined half (16 bit) */
+
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV 6
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_UB 7
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_SB 8
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_UH 9
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_SH 10
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_UI 11
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_SI 12
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU 13
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_UB 14
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_SB 15
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_UH 16
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_SH 17
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_UI 18
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_SI 19
+/* Flags: I | E | K */
+#define SLJIT_NOT 20
+/* Flags: I | E | O | K */
+#define SLJIT_NEG 21
+/* Count leading zeroes
+ Flags: I | E | K */
+#define SLJIT_CLZ 22
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw);
+
+/* Flags: I | E | O | C | K */
+#define SLJIT_ADD 23
+/* Flags: I | C | K */
+#define SLJIT_ADDC 24
+/* Flags: I | E | S | U | O | C | K */
+#define SLJIT_SUB 25
+/* Flags: I | C | K */
+#define SLJIT_SUBC 26
+/* Note: integer mul
+ Flags: I | O (see SLJIT_C_MUL_*) | K */
+#define SLJIT_MUL 27
+/* Flags: I | E | K */
+#define SLJIT_AND 28
+/* Flags: I | E | K */
+#define SLJIT_OR 29
+/* Flags: I | E | K */
+#define SLJIT_XOR 30
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the operation is undefined. */
+#define SLJIT_SHL 31
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the operation is undefined. */
+#define SLJIT_LSHR 32
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the operation is undefined. */
+#define SLJIT_ASHR 33
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+/* The following function is a helper function for sljit_emit_op_custom.
+ It returns with the real machine register index of any SLJIT_TEMPORARY
+ SLJIT_SAVED or SLJIT_LOCALS register.
+ Note: it returns with -1 for virtual registers (all EREGs on x86-32).
+ Note: register returned by SLJIT_LOCALS_REG is not necessary the real
+ stack pointer register of the target architecture. */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg);
+
+/* Any instruction can be inserted into the instruction stream by
+ sljit_emit_op_custom. It has a similar purpose as inline assembly.
+ The size parameter must match to the instruction size of the target
+ architecture:
+
+ x86: 0 < size <= 15. The instruction argument can be byte aligned.
+ Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
+ if size == 4, the instruction argument must be 4 byte aligned.
+ Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size);
+
+/* Returns with non-zero if fpu is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void);
+
+/* Note: dst is the left and src is the right operand for SLJIT_FCMP.
+ Note: NaN check is always performed. If SLJIT_C_FLOAT_NAN is set,
+ the comparison result is unpredictable.
+ Flags: E | S (see SLJIT_C_FLOAT_*) */
+#define SLJIT_FCMP 34
+/* Flags: - (never set any flags) */
+#define SLJIT_FMOV 35
+/* Flags: - (never set any flags) */
+#define SLJIT_FNEG 36
+/* Flags: - (never set any flags) */
+#define SLJIT_FABS 37
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw);
+
+/* Flags: - (never set any flags) */
+#define SLJIT_FADD 38
+/* Flags: - (never set any flags) */
+#define SLJIT_FSUB 39
+/* Flags: - (never set any flags) */
+#define SLJIT_FMUL 40
+/* Flags: - (never set any flags) */
+#define SLJIT_FDIV 41
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+/* Label and jump instructions. */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
+
+/* Invert conditional instruction: xor (^) with 0x1 */
+#define SLJIT_C_EQUAL 0
+#define SLJIT_C_ZERO 0
+#define SLJIT_C_NOT_EQUAL 1
+#define SLJIT_C_NOT_ZERO 1
+
+#define SLJIT_C_LESS 2
+#define SLJIT_C_GREATER_EQUAL 3
+#define SLJIT_C_GREATER 4
+#define SLJIT_C_LESS_EQUAL 5
+#define SLJIT_C_SIG_LESS 6
+#define SLJIT_C_SIG_GREATER_EQUAL 7
+#define SLJIT_C_SIG_GREATER 8
+#define SLJIT_C_SIG_LESS_EQUAL 9
+
+#define SLJIT_C_OVERFLOW 10
+#define SLJIT_C_NOT_OVERFLOW 11
+
+#define SLJIT_C_MUL_OVERFLOW 12
+#define SLJIT_C_MUL_NOT_OVERFLOW 13
+
+#define SLJIT_C_FLOAT_EQUAL 14
+#define SLJIT_C_FLOAT_NOT_EQUAL 15
+#define SLJIT_C_FLOAT_LESS 16
+#define SLJIT_C_FLOAT_GREATER_EQUAL 17
+#define SLJIT_C_FLOAT_GREATER 18
+#define SLJIT_C_FLOAT_LESS_EQUAL 19
+#define SLJIT_C_FLOAT_NAN 20
+#define SLJIT_C_FLOAT_NOT_NAN 21
+
+#define SLJIT_JUMP 22
+#define SLJIT_FAST_CALL 23
+#define SLJIT_CALL0 24
+#define SLJIT_CALL1 25
+#define SLJIT_CALL2 26
+#define SLJIT_CALL3 27
+
+/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
+
+/* The target can be changed during runtime (see: sljit_set_jump_addr). */
+#define SLJIT_REWRITABLE_JUMP 0x1000
+
+/* Emit a jump instruction. The destination is not set, only the type of the jump.
+ type must be between SLJIT_C_EQUAL and SLJIT_CALL3
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ Flags: - (never set any flags) for both conditional and unconditional jumps.
+ Flags: destroy all flags for calls. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type);
+
+/* Basic arithmetic comparison. In most architectures it is implemented as
+ an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
+ appropriate flags) followed by a sljit_emit_jump. However some
+ architectures (i.e: MIPS) may employ special optimizations here. It is
+ suggested to use this comparison form when appropriate.
+ type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP
+ Flags: destroy flags. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+/* Basic floating point comparison. In most architectures it is implemented as
+ an SLJIT_FCMP operation (setting appropriate flags) followed by a
+ sljit_emit_jump. However some architectures (i.e: MIPS) may employ
+ special optimizations here. It is suggested to use this comparison form
+ when appropriate.
+ type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_NOT_NAN
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ Flags: destroy flags.
+ Note: if either operand is NaN, the behaviour is undefined for
+ type <= SLJIT_C_FLOAT_LESS_EQUAL. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+/* Set the destination of the jump to this label. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
+/* Only for jumps defined with SLJIT_REWRITABLE_JUMP flag.
+ Note: use sljit_emit_ijump for fixed jumps. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
+
+/* Call function or jump anywhere. Both direct and indirect form
+ type must be between SLJIT_JUMP and SLJIT_CALL3
+ Direct form: set src to SLJIT_IMM() and srcw to the address
+ Indirect form: any other valid addressing mode
+ Flags: - (never set any flags) for unconditional jumps.
+ Flags: destroy all flags for calls. */
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw);
+
+/* If op == SLJIT_MOV:
+ Set dst to 1 if condition is fulfilled, 0 otherwise
+ type must be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_NOT_NAN
+ Flags: - (never set any flags)
+ If op == SLJIT_OR
+ Dst is used as src as well, and set its lowest bit to 1 if
+ the condition is fulfilled. Otherwise it does nothing.
+ Flags: E | K
+ Note: sljit_emit_cond_value does nothing, if dst is SLJIT_UNUSED (regardless of op). */
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type);
+
+/* The constant can be changed runtime (see: sljit_set_const)
+ Flags: - (never set any flags) */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value);
+
+/* After the code generation the address for label, jump and const instructions
+ are computed. Since these structures are freed sljit_free_compiler, the
+ addresses must be preserved by the user program elsewere. */
+static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
+static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
+static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
+
+/* Only the address is required to rewrite the code. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant);
+
+/* --------------------------------------------------------------------- */
+/* Miscellaneous utility functions */
+/* --------------------------------------------------------------------- */
+
+#define SLJIT_MAJOR_VERSION 0
+#define SLJIT_MINOR_VERSION 87
+
+/* Get the human readable name of the platfrom.
+ Can be useful for debugging on platforms like ARM, where ARM and
+ Thumb2 functions can be mixed. */
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
+
+/* Portble helper function to get an offset of a member. */
+#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10)
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+/* This global lock is useful to compile common functions. */
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
+#endif
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+/* The sljit_stack is a utiliy feature of sljit, which allocates a
+ writable memory region between base (inclusive) and limit (exclusive).
+ Both base and limit is a pointer, and base is always <= than limit.
+ This feature uses the "address space reserve" feature
+ of modern operating systems. Basically we don't need to allocate a
+ huge memory block in one step for the worst case, we can start with
+ a smaller chunk and extend it later. Since the address space is
+ reserved, the data never copied to other regions, thus it is safe
+ to store pointers here. */
+
+/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more).
+ Note: stack growing should not happen in small steps: 4k, 16k or even
+ bigger growth is better.
+ Note: this structure may not be supported by all operating systems.
+ Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
+ is not defined. */
+
+struct sljit_stack {
+ /* User data, anything can be stored here.
+ Starting with the same value as base. */
+ sljit_uw top;
+ /* These members are read only. */
+ sljit_uw base;
+ sljit_uw limit;
+ sljit_uw max_limit;
+};
+
+/* Returns NULL if unsuccessful.
+ Note: limit and max_limit contains the size for stack allocation
+ Note: the top field is initialized to base. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack);
+
+/* Can be used to increase (allocate) or decrease (free) the memory area.
+ Returns with a non-zero value if unsuccessful. If new_limit is greater than
+ max_limit, it will fail. It is very easy to implement a stack data structure,
+ since the growth ratio can be added to the current limit, and sljit_stack_resize
+ will do all the necessary checks. The fields of the stack are not changed if
+ sljit_stack_resize fails. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
+
+#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
+
+#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+
+/* Get the entry address of a given function. */
+#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name)
+
+#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+/* All JIT related code should be placed in the same context (library, binary, etc.). */
+
+#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name)
+
+/* For powerpc64, the function pointers point to a context descriptor. */
+struct sljit_function_context {
+ sljit_w addr;
+ sljit_w r2;
+ sljit_w r11;
+};
+
+/* Fill the context arguments using the addr and the function.
+ If func_ptr is NULL, it will not be set to the address of context
+ If addr is NULL, the function address also comes from the func pointer. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func);
+
+#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+#endif /* _SLJIT_LIR_H_ */
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
new file mode 100644
index 0000000000..a51536b4a7
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
@@ -0,0 +1,1913 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "ARM-Thumb2" SLJIT_CPUINFO;
+}
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define TMP_PC (SLJIT_NO_REGISTERS + 4)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
+ 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15
+};
+
+#define COPY_BITS(src, from, to, bits) \
+ ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to))
+
+/* Thumb16 encodings. */
+#define RD3(rd) (reg_map[rd])
+#define RN3(rn) (reg_map[rn] << 3)
+#define RM3(rm) (reg_map[rm] << 6)
+#define RDN3(rdn) (reg_map[rdn] << 8)
+#define IMM3(imm) (imm << 6)
+#define IMM8(imm) (imm)
+
+/* Thumb16 helpers. */
+#define SET_REGS44(rd, rn) \
+ ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4))
+#define IS_2_LO_REGS(reg1, reg2) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7)
+#define IS_3_LO_REGS(reg1, reg2, reg3) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)
+
+/* Thumb32 encodings. */
+#define RD4(rd) (reg_map[rd] << 8)
+#define RN4(rn) (reg_map[rn] << 16)
+#define RM4(rm) (reg_map[rm])
+#define RT4(rt) (reg_map[rt] << 12)
+#define DD4(dd) ((dd) << 12)
+#define DN4(dn) ((dn) << 16)
+#define DM4(dm) (dm)
+#define IMM5(imm) \
+ (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6))
+#define IMM12(imm) \
+ (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))
+
+typedef sljit_ui sljit_ins;
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* dot '.' changed to _
+ I immediate form (possibly followed by number of immediate bits). */
+#define ADCI 0xf1400000
+#define ADCS 0x4140
+#define ADC_W 0xeb400000
+#define ADD 0x4400
+#define ADDS 0x1800
+#define ADDSI3 0x1c00
+#define ADDSI8 0x3000
+#define ADD_W 0xeb000000
+#define ADDWI 0xf2000000
+#define ADD_SP 0xb000
+#define ADD_W 0xeb000000
+#define ADD_WI 0xf1000000
+#define ANDI 0xf0000000
+#define ANDS 0x4000
+#define AND_W 0xea000000
+#define ASRS 0x4100
+#define ASRSI 0x1000
+#define ASR_W 0xfa40f000
+#define ASR_WI 0xea4f0020
+#define BICI 0xf0200000
+#define BKPT 0xbe00
+#define BLX 0x4780
+#define BX 0x4700
+#define CLZ 0xfab0f080
+#define CMPI 0x2800
+#define CMP_W 0xebb00f00
+#define EORI 0xf0800000
+#define EORS 0x4040
+#define EOR_W 0xea800000
+#define IT 0xbf00
+#define LSLS 0x4080
+#define LSLSI 0x0000
+#define LSL_W 0xfa00f000
+#define LSL_WI 0xea4f0000
+#define LSRS 0x40c0
+#define LSRSI 0x0800
+#define LSR_W 0xfa20f000
+#define LSR_WI 0xea4f0010
+#define MOV 0x4600
+#define MOVS 0x0000
+#define MOVSI 0x2000
+#define MOVT 0xf2c00000
+#define MOVW 0xf2400000
+#define MOV_W 0xea4f0000
+#define MOV_WI 0xf04f0000
+#define MUL 0xfb00f000
+#define MVNS 0x43c0
+#define MVN_W 0xea6f0000
+#define MVN_WI 0xf06f0000
+#define NOP 0xbf00
+#define ORNI 0xf0600000
+#define ORRI 0xf0400000
+#define ORRS 0x4300
+#define ORR_W 0xea400000
+#define POP 0xbd00
+#define POP_W 0xe8bd0000
+#define PUSH 0xb500
+#define PUSH_W 0xe92d0000
+#define RSB_WI 0xf1c00000
+#define RSBSI 0x4240
+#define SBCI 0xf1600000
+#define SBCS 0x4180
+#define SBC_W 0xeb600000
+#define SMULL 0xfb800000
+#define STR_SP 0x9000
+#define SUBS 0x1a00
+#define SUBSI3 0x1e00
+#define SUBSI8 0x3800
+#define SUB_W 0xeba00000
+#define SUBWI 0xf2a00000
+#define SUB_SP 0xb080
+#define SUB_WI 0xf1a00000
+#define SXTB 0xb240
+#define SXTB_W 0xfa4ff080
+#define SXTH 0xb200
+#define SXTH_W 0xfa0ff080
+#define TST 0x4200
+#define UMULL 0xfba00000
+#define UXTB 0xb2c0
+#define UXTB_W 0xfa5ff080
+#define UXTH 0xb280
+#define UXTH_W 0xfa1ff080
+#define VABS_F64 0xeeb00bc0
+#define VADD_F64 0xee300b00
+#define VCMP_F64 0xeeb40b40
+#define VDIV_F64 0xee800b00
+#define VMOV_F64 0xeeb00b40
+#define VMRS 0xeef1fa10
+#define VMUL_F64 0xee200b00
+#define VNEG_F64 0xeeb10b40
+#define VSTR 0xed000b00
+#define VSUB_F64 0xee300b40
+
+static int push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_uh *ptr;
+ SLJIT_ASSERT(!(inst & 0xffff0000));
+
+ ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh));
+ FAIL_IF(!ptr);
+ *ptr = inst;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr++ = inst >> 16;
+ *ptr = inst;
+ compiler->size += 2;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_imm32_const(struct sljit_compiler *compiler, int dst, sljit_uw imm)
+{
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+}
+
+static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm)
+{
+ int dst = inst[1] & 0x0f00;
+ SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
+ inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1);
+ inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff);
+ inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1);
+ inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
+}
+
+static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code)
+{
+ sljit_w diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+ if (jump->flags & JUMP_ADDR) {
+ /* Branch to ARM code is not optimized yet. */
+ if (!(jump->u.target & 0x1))
+ return 0;
+ diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)) >> 1;
+ }
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)) >> 1;
+ }
+
+ if (jump->flags & IS_CONDITIONAL) {
+ SLJIT_ASSERT(!(jump->flags & IS_BL));
+ if (diff <= 127 && diff >= -128) {
+ jump->flags |= B_TYPE1;
+ return 5;
+ }
+ if (diff <= 524287 && diff >= -524288) {
+ jump->flags |= B_TYPE2;
+ return 4;
+ }
+ /* +1 comes from the prefix IT instruction. */
+ diff--;
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= B_TYPE3;
+ return 3;
+ }
+ }
+ else if (jump->flags & IS_BL) {
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= BL_TYPE6;
+ return 3;
+ }
+ }
+ else {
+ if (diff <= 1023 && diff >= -1024) {
+ jump->flags |= B_TYPE4;
+ return 4;
+ }
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= B_TYPE5;
+ return 3;
+ }
+ }
+
+ return 0;
+}
+
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush)
+{
+ sljit_uh* inst = (sljit_uh*)addr;
+ modify_imm32_const(inst, new_addr);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+ }
+}
+
+static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
+{
+ int type = (jump->flags >> 4) & 0xf;
+ sljit_w diff;
+ sljit_uh *jump_inst;
+ int s, j1, j2;
+
+ if (SLJIT_UNLIKELY(type == 0)) {
+ inline_set_jump_addr(jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+ return;
+ }
+
+ if (jump->flags & JUMP_ADDR) {
+ SLJIT_ASSERT(jump->u.target & 0x1);
+ diff = ((sljit_w)jump->u.target - (sljit_w)(jump->addr + 4)) >> 1;
+ }
+ else
+ diff = ((sljit_w)(jump->u.label->addr) - (sljit_w)(jump->addr + 4)) >> 1;
+ jump_inst = (sljit_uh*)jump->addr;
+
+ switch (type) {
+ case 1:
+ /* Encoding T1 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff);
+ return;
+ case 2:
+ /* Encoding T3 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1);
+ jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff);
+ return;
+ case 3:
+ SLJIT_ASSERT(jump->flags & IS_CONDITIONAL);
+ *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8;
+ diff--;
+ type = 5;
+ break;
+ case 4:
+ /* Encoding T2 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xe000 | (diff & 0x7ff);
+ return;
+ }
+
+ SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);
+
+ /* Really complex instruction form for branches. */
+ s = (diff >> 23) & 0x1;
+ j1 = (~(diff >> 21) ^ s) & 0x1;
+ j2 = (~(diff >> 22) ^ s) & 0x1;
+ jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10);
+ jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff);
+
+ /* The others have a common form. */
+ if (type == 5) /* Encoding T4 of 'B' instruction */
+ jump_inst[1] |= 0x9000;
+ else if (type == 6) /* Encoding T1 of 'BL' instruction */
+ jump_inst[1] |= 0xd000;
+ else
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_uh *code;
+ sljit_uh *code_ptr;
+ sljit_uh *buf_ptr;
+ sljit_uh *buf_end;
+ sljit_uw half_count;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ half_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_uh*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 1);
+ do {
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= half_count);
+ SLJIT_ASSERT(!jump || jump->addr >= half_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= half_count);
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)code_ptr) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == half_count) {
+ jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_CONDITIONAL) ? 10 : 8);
+ code_ptr -= detect_jump_type(jump, code_ptr, code);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == half_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ half_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)code_ptr) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ set_jump_instruction(jump);
+ jump = jump->next;
+ }
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_uh);
+ /* Set thumb mode flag. */
+ return (void*)((sljit_uw)code | 0x1);
+}
+
+#define INVALID_IMM 0x80000000
+static sljit_uw get_imm(sljit_uw imm)
+{
+ /* Thumb immediate form. */
+ int counter;
+
+ if (imm <= 0xff)
+ return imm;
+
+ if ((imm & 0xffff) == (imm >> 16)) {
+ /* Some special cases. */
+ if (!(imm & 0xff00))
+ return (1 << 12) | (imm & 0xff);
+ if (!(imm & 0xff))
+ return (2 << 12) | ((imm >> 8) & 0xff);
+ if ((imm & 0xff00) == ((imm & 0xff) << 8))
+ return (3 << 12) | (imm & 0xff);
+ }
+
+ /* Assembly optimization: count leading zeroes? */
+ counter = 8;
+ if (!(imm & 0xffff0000)) {
+ counter += 16;
+ imm <<= 16;
+ }
+ if (!(imm & 0xff000000)) {
+ counter += 8;
+ imm <<= 8;
+ }
+ if (!(imm & 0xf0000000)) {
+ counter += 4;
+ imm <<= 4;
+ }
+ if (!(imm & 0xc0000000)) {
+ counter += 2;
+ imm <<= 2;
+ }
+ if (!(imm & 0x80000000)) {
+ counter += 1;
+ imm <<= 1;
+ }
+ /* Since imm >= 128, this must be true. */
+ SLJIT_ASSERT(counter <= 31);
+
+ if (imm & 0x00ffffff)
+ return INVALID_IMM; /* Cannot be encoded. */
+
+ return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);
+}
+
+static int load_immediate(struct sljit_compiler *compiler, int dst, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+ if (imm >= 0x10000) {
+ tmp = get_imm(imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MOV_WI | RD4(dst) | tmp);
+ tmp = get_imm(~imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MVN_WI | RD4(dst) | tmp);
+ }
+
+ /* set low 16 bits, set hi 16 bits to 0. */
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+
+ /* set hi 16 bit if needed. */
+ if (imm >= 0x10000)
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+ return SLJIT_SUCCESS;
+}
+
+#define ARG1_IMM 0x0010000
+#define ARG2_IMM 0x0020000
+#define KEEP_FLAGS 0x0040000
+#define SET_MULOV 0x0080000
+/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS 0x0100000
+#define UNUSED_RETURN 0x0200000
+#define SLOW_DEST 0x0400000
+#define SLOW_SRC1 0x0800000
+#define SLOW_SRC2 0x1000000
+
+static int emit_op_imm(struct sljit_compiler *compiler, int flags, int dst, sljit_uw arg1, sljit_uw arg2)
+{
+ /* dst must be register, TMP_REG1
+ arg1 must be register, TMP_REG1, imm
+ arg2 must be register, TMP_REG2, imm */
+ int reg;
+ sljit_uw imm;
+
+ if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
+ /* Both are immediates. */
+ flags &= ~ARG1_IMM;
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+
+ if (flags & (ARG1_IMM | ARG2_IMM)) {
+ reg = (flags & ARG2_IMM) ? arg1 : arg2;
+ imm = (flags & ARG2_IMM) ? arg2 : arg1;
+
+ switch (flags & 0xffff) {
+ case SLJIT_MOV:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
+ return load_immediate(compiler, dst, imm);
+ case SLJIT_NOT:
+ if (!(flags & SET_FLAGS))
+ return load_immediate(compiler, dst, ~imm);
+ /* Since the flags should be set, we just fallback to the register mode.
+ Although I could do some clever things here, "NOT IMM" does not worth the efforts. */
+ break;
+ case SLJIT_CLZ:
+ /* No form with immediate operand. */
+ break;
+ case SLJIT_ADD:
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+ if (imm <= 0x7)
+ return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
+ if (reg == dst && imm <= 0xff)
+ return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));
+ }
+ if (imm <= 0xfff && !(flags & SET_FLAGS))
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_ADDC:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SUB:
+ if (flags & ARG2_IMM) {
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+ if (imm <= 0x7)
+ return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
+ if (imm <= 0xff) {
+ if (reg == dst)
+ return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));
+ if (flags & UNUSED_RETURN)
+ return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
+ }
+ }
+ if (imm <= 0xfff && !(flags & SET_FLAGS))
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ else {
+ if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst))
+ return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ break;
+ case SLJIT_SUBC:
+ if (flags & ARG2_IMM) {
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ break;
+ case SLJIT_MUL:
+ /* No form with immediate operand. */
+ break;
+ case SLJIT_AND:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1));
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_OR:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1));
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_XOR:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SHL:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ case SLJIT_LSHR:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ case SLJIT_ASHR:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (flags & ARG2_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
+ arg2 = TMP_REG2;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+ }
+
+ /* Both arguments are registers. */
+ switch (flags & 0xffff) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
+ case SLJIT_MOV_UB:
+ case SLJIT_MOVU_UB:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_SB:
+ case SLJIT_MOVU_SB:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_UH:
+ case SLJIT_MOVU_UH:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_SH:
+ case SLJIT_MOVU_SH:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_NOT:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2));
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)));
+ if (flags & SET_FLAGS) {
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, CMPI | RDN3(dst));
+ return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst));
+ }
+ return SLJIT_SUCCESS;
+ case SLJIT_ADD:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ if (dst == arg1 && !(flags & SET_FLAGS))
+ return push_inst16(compiler, ADD | SET_REGS44(dst, arg2));
+ return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ADDC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUB:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUBC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_MUL:
+ if (!(flags & SET_FLAGS))
+ return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
+ SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2);
+ FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
+ case SLJIT_AND:
+ if (!(flags & KEEP_FLAGS)) {
+ if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
+ if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
+ return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
+ }
+ return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_OR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_XOR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SHL:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_LSHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ASHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#define STORE 0x01
+#define SIGNED 0x02
+
+#define WORD_SIZE 0x00
+#define BYTE_SIZE 0x04
+#define HALF_SIZE 0x08
+
+#define UPDATE 0x10
+#define ARG_TEST 0x20
+
+#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE)))
+#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift)))
+
+/*
+ 1st letter:
+ w = word
+ b = byte
+ h = half
+
+ 2nd letter:
+ s = signed
+ u = unsigned
+
+ 3rd letter:
+ l = load
+ s = store
+*/
+
+static SLJIT_CONST sljit_uw sljit_mem16[12] = {
+/* w u l */ 0x5800 /* ldr */,
+/* w u s */ 0x5000 /* str */,
+/* w s l */ 0x5800 /* ldr */,
+/* w s s */ 0x5000 /* str */,
+
+/* b u l */ 0x5c00 /* ldrb */,
+/* b u s */ 0x5400 /* strb */,
+/* b s l */ 0x5600 /* ldrsb */,
+/* b s s */ 0x5400 /* strb */,
+
+/* h u l */ 0x5a00 /* ldrh */,
+/* h u s */ 0x5200 /* strh */,
+/* h s l */ 0x5e00 /* ldrsh */,
+/* h s s */ 0x5200 /* strh */,
+};
+
+static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = {
+/* w u l */ 0x6800 /* ldr imm5 */,
+/* w u s */ 0x6000 /* str imm5 */,
+/* w s l */ 0x6800 /* ldr imm5 */,
+/* w s s */ 0x6000 /* str imm5 */,
+
+/* b u l */ 0x7800 /* ldrb imm5 */,
+/* b u s */ 0x7000 /* strb imm5 */,
+/* b s l */ 0x0000 /* not allowed */,
+/* b s s */ 0x7000 /* strb imm5 */,
+
+/* h u l */ 0x8800 /* ldrh imm5 */,
+/* h u s */ 0x8000 /* strh imm5 */,
+/* h s l */ 0x0000 /* not allowed */,
+/* h s s */ 0x8000 /* strh imm5 */,
+};
+
+#define MEM_IMM8 0xc00
+#define MEM_IMM12 0x800000
+static SLJIT_CONST sljit_uw sljit_mem32[12] = {
+/* w u l */ 0xf8500000 /* ldr.w */,
+/* w u s */ 0xf8400000 /* str.w */,
+/* w s l */ 0xf8500000 /* ldr.w */,
+/* w s s */ 0xf8400000 /* str.w */,
+
+/* b u l */ 0xf8100000 /* ldrb.w */,
+/* b u s */ 0xf8000000 /* strb.w */,
+/* b s l */ 0xf9100000 /* ldrsb.w */,
+/* b s s */ 0xf8000000 /* strb.w */,
+
+/* h u l */ 0xf8300000 /* ldrh.w */,
+/* h u s */ 0xf8200000 /* strsh.w */,
+/* h s l */ 0xf9300000 /* ldrsh.w */,
+/* h s s */ 0xf8200000 /* strsh.w */,
+};
+
+/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
+static int emit_set_delta(struct sljit_compiler *compiler, int dst, int reg, sljit_w value)
+{
+ if (value >= 0) {
+ if (value <= 0xfff)
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value);
+ }
+ else {
+ value = -value;
+ if (value <= 0xfff)
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value);
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ int tmp;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ if ((arg & 0xf) && !(arg & 0xf0) && argw <= 0xff && argw >= -0xff) {
+ flags &= ~UPDATE;
+ arg &= 0xf;
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ if (argw >= 0)
+ argw |= 0x200;
+ else {
+ argw = -argw;
+ }
+ SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff);
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw));
+ return -1;
+ }
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ tmp = (arg >> 4) & 0xf;
+ arg &= 0xf;
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ if (!argw && IS_3_LO_REGS(reg, arg, tmp))
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp)));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4)));
+ return -1;
+ }
+
+ if (!(arg & 0xf) || argw > 0xfff || argw < -0xff)
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ arg &= 0xf;
+ if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {
+ tmp = 3;
+ if (IS_WORD_SIZE(flags)) {
+ if (OFFSET_CHECK(0x1f, 2))
+ tmp = 2;
+ }
+ else if (flags & BYTE_SIZE)
+ {
+ if (OFFSET_CHECK(0x1f, 0))
+ tmp = 0;
+ }
+ else {
+ SLJIT_ASSERT(flags & HALF_SIZE);
+ if (OFFSET_CHECK(0x1f, 1))
+ tmp = 1;
+ }
+
+ if (tmp != 3) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp))));
+ return -1;
+ }
+ }
+
+ /* SP based immediate. */
+ if (SLJIT_UNLIKELY(arg == SLJIT_LOCALS_REG) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
+ FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2)));
+ return -1;
+ }
+
+ if (argw >= 0)
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw));
+ return -1;
+}
+
+/* see getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ /* Simple operation except for updates. */
+ if ((arg & 0xf0) || !(next_arg & SLJIT_MEM))
+ return 0;
+
+ if (!(arg & 0xf)) {
+ if ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff)
+ return 1;
+ return 0;
+ }
+
+ if (argw == next_argw)
+ return 1;
+
+ if (arg == next_arg && ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff))
+ return 1;
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_w tmp;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_r = (flags & STORE) ? TMP_REG3 : reg;
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ flags &= ~UPDATE;
+ /* Update only applies if a base register exists. */
+ if (arg & 0xf) {
+ /* There is no caching here. */
+ tmp = (arg & 0xf0) >> 4;
+ arg &= 0xf;
+
+ if (!tmp) {
+ if (!(argw & ~0xfff)) {
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw));
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM) {
+ if (argw == compiler->cache_argw) {
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ if (argw) {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ argw &= 0x3;
+ if (!argw && IS_3_LO_REGS(reg, arg, tmp)) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp)));
+ return push_inst16(compiler, ADD | SET_REGS44(arg, tmp));
+ }
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4)));
+ return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(tmp) | (argw << 6));
+ }
+ }
+
+ SLJIT_ASSERT(!(arg & 0xf0));
+
+ if (compiler->cache_arg == arg) {
+ if (!((argw - compiler->cache_argw) & ~0xfff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | (argw - compiler->cache_argw));
+ if (!((compiler->cache_argw - argw) & ~0xff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+ }
+ }
+
+ next_arg = (arg & 0xf) && (arg == next_arg);
+ arg &= 0xf;
+ if (arg && compiler->cache_arg == SLJIT_MEM && compiler->cache_argw == argw)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+
+ compiler->cache_argw = argw;
+ if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+
+ if (next_arg) {
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg)));
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ }
+
+ if (arg)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+}
+
+static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_ins push;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ push = (1 << 4);
+ if (saveds >= 5)
+ push |= 1 << 11;
+ if (saveds >= 4)
+ push |= 1 << 10;
+ if (saveds >= 3)
+ push |= 1 << 8;
+ if (saveds >= 2)
+ push |= 1 << 7;
+ if (saveds >= 1)
+ push |= 1 << 6;
+ if (temporaries >= 5)
+ push |= 1 << 5;
+ FAIL_IF(saveds >= 3
+ ? push_inst32(compiler, PUSH_W | (1 << 14) | push)
+ : push_inst16(compiler, PUSH | push));
+
+ /* Stack must be aligned to 8 bytes: */
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+ if (local_size > 0) {
+ if (local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, local_size));
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ sljit_ins pop;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0) {
+ if (compiler->local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, compiler->local_size));
+ }
+
+ pop = (1 << 4);
+ if (compiler->saveds >= 5)
+ pop |= 1 << 11;
+ if (compiler->saveds >= 4)
+ pop |= 1 << 10;
+ if (compiler->saveds >= 3)
+ pop |= 1 << 8;
+ if (compiler->saveds >= 2)
+ pop |= 1 << 7;
+ if (compiler->saveds >= 1)
+ pop |= 1 << 6;
+ if (compiler->temporaries >= 5)
+ pop |= 1 << 5;
+ return compiler->saveds >= 3
+ ? push_inst32(compiler, POP_W | (1 << 15) | pop)
+ : push_inst16(compiler, POP | pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);
+extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ push_inst16(compiler, BKPT);
+ break;
+ case SLJIT_NOP:
+ push_inst16(compiler, NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 8)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 16)
+ | reg_map[SLJIT_TEMPORARY_REG2]);
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ if (compiler->temporaries >= 4) {
+ FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
+ FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
+ } else if (compiler->temporaries >= 3)
+ FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+ if (compiler->temporaries >= 4) {
+ FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
+ return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
+ } else if (compiler->temporaries >= 3)
+ return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int op_type, dst_r, flags;
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ op_type = GET_OPCODE(op);
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+
+ if (op_type >= SLJIT_MOV && op_type <= SLJIT_MOVU_SI) {
+ switch (op_type) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ flags = WORD_SIZE;
+ break;
+ case SLJIT_MOV_UB:
+ flags = BYTE_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOV_SB:
+ flags = BYTE_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOV_UH:
+ flags = HALF_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOV_SH:
+ flags = HALF_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (signed short)srcw;
+ break;
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ flags = WORD_SIZE | UPDATE;
+ break;
+ case SLJIT_MOVU_UB:
+ flags = BYTE_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOVU_SB:
+ flags = BYTE_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOVU_UH:
+ flags = HALF_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOVU_SH:
+ flags = HALF_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (signed short)srcw;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ flags = 0;
+ break;
+ }
+
+ if (src & SLJIT_IMM)
+ FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
+ } else {
+ if (dst_r != TMP_REG1)
+ return emit_op_imm(compiler, op_type, dst_r, TMP_REG1, src);
+ dst_r = src;
+ }
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (op_type == SLJIT_NEG) {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, GET_FLAGS(op) | SLJIT_SUB, dst, dstw, SLJIT_IMM, 0, src, srcw);
+ }
+
+ flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+ if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
+ src = TMP_REG2;
+ }
+
+ if (src & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ srcw = src;
+
+ emit_op_imm(compiler, flags | op_type, dst_r, TMP_REG1, srcw);
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r, flags;
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+ flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+
+ if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+
+ if (src1 & SLJIT_MEM)
+ src1 = TMP_REG1;
+ if (src2 & SLJIT_MEM)
+ src2 = TMP_REG2;
+
+ if (src1 & SLJIT_IMM)
+ flags |= ARG1_IMM;
+ else
+ src1w = src1;
+ if (src2 & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ src2w = src2;
+
+ if (dst == SLJIT_UNUSED)
+ flags |= UNUSED_RETURN;
+
+ if (GET_OPCODE(op) == SLJIT_MUL && (op & SLJIT_SET_O))
+ flags |= SET_MULOV;
+
+ emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 2 || size == 4);
+
+ if (size == 2)
+ return push_inst16(compiler, *(sljit_uh*)instruction);
+ return push_inst32(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ return 1;
+}
+
+static int emit_fop_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ sljit_w tmp;
+ sljit_w inst = VSTR | ((flags & STORE) ? 0 : 0x00100000);
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & 0xf) | RM4((arg & 0xf0) >> 4) | ((argw & 0x3) << 6)));
+ arg = SLJIT_MEM | TMP_REG2;
+ argw = 0;
+ }
+
+ if (arg & 0xf) {
+ if (!(argw & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2));
+ if (!(-argw & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(arg & 0xf) | DD4(reg) | (-argw >> 2));
+ }
+
+ SLJIT_ASSERT(!(arg & 0xf0));
+ if (compiler->cache_arg == arg) {
+ tmp = argw - compiler->cache_argw;
+ if (!(tmp & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2));
+ if (!(-tmp & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ if (SLJIT_UNLIKELY(!(arg & 0xf)))
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ else if (emit_set_delta(compiler, TMP_REG3, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED)
+ FAIL_IF(compiler->error);
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ if (arg & 0xf)
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & 0xf))));
+ }
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
+ dst = TMP_FREG1;
+ }
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG2, src, srcw);
+ src = TMP_FREG2;
+ }
+ FAIL_IF(push_inst32(compiler, VCMP_F64 | DD4(dst) | DM4(src)));
+ return push_inst32(compiler, VMRS);
+ }
+
+ dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1;
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, dst_r, src, srcw);
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_FMOV:
+ if (src != dst_r)
+ FAIL_IF(push_inst32(compiler, VMOV_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst32(compiler, VNEG_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst32(compiler, VABS_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1;
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst32(compiler, VADD_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst32(compiler, VSUB_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst32(compiler, VMUL_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst32(compiler, VDIV_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
+ else if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw))
+ return compiler->error;
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3)));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src)));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0));
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2)));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst16(compiler, BLX | RN3(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x0;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x1;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x3;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x2;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x8;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x9;
+
+ case SLJIT_C_SIG_LESS:
+ return 0xb;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0xa;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0xc;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0xd;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_FLOAT_NAN:
+ return 0x6;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x7;
+
+ default: /* SLJIT_JUMP */
+ return 0xe;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ int cc;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+ PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ if (type < SLJIT_JUMP) {
+ jump->flags |= IS_CONDITIONAL;
+ cc = get_cc(type);
+ jump->flags |= cc << 8;
+ PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ }
+
+ jump->addr = compiler->size;
+ if (type <= SLJIT_JUMP)
+ PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));
+ else {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
+ }
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)));
+ }
+ else {
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
+
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw));
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst16(compiler, BLX | RN3(TMP_REG1));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int dst_r;
+ sljit_uw cc;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ cc = get_cc(type);
+ if (GET_OPCODE(op) == SLJIT_OR && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ FAIL_IF(push_inst32(compiler, ORRI | RN4(dst) | RD4(dst) | 0x1));
+ if (op & SLJIT_SET_E) {
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, ORRS | RD3(dst) | RN3(dst));
+ return push_inst32(compiler, ORR_W | SET_FLAGS | RD4(TMP_REG1) | RN4(dst) | RM4(dst));
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = TMP_REG2;
+ if (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && reg_map[dst] <= 7)
+ dst_r = dst;
+
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
+ FAIL_IF(push_inst16(compiler, MOVSI | 0x1 | RDN3(dst_r)));
+ FAIL_IF(push_inst16(compiler, MOVSI | 0x0 | RDN3(dst_r)));
+
+ if (dst_r == TMP_REG2) {
+ if (GET_OPCODE(op) == SLJIT_OR) {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG2, 0);
+ }
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw);
+ else
+ return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int dst_r;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ inline_set_jump_addr(addr, new_addr, 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_uh* inst = (sljit_uh*)addr;
+ modify_imm32_const(inst, new_constant);
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
new file mode 100644
index 0000000000..e3a5873247
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
@@ -0,0 +1,2424 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return "ARMv7" SLJIT_CPUINFO;
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ return "ARMv5" SLJIT_CPUINFO;
+#else
+#error "Internal error: Unknown ARM architecture"
+#endif
+}
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define TMP_PC (SLJIT_NO_REGISTERS + 4)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* In ARM instruction words.
+ Cache lines are usually 32 byte aligned. */
+#define CONST_POOL_ALIGNMENT 8
+#define CONST_POOL_EMPTY 0xffffffff
+
+#define ALIGN_INSTRUCTION(ptr) \
+ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))
+#define MAX_DIFFERENCE(max_diff) \
+ (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
+ 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15
+};
+
+#define RM(rm) (reg_map[rm])
+#define RD(rd) (reg_map[rd] << 12)
+#define RN(rn) (reg_map[rn] << 16)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* The instruction includes the AL condition.
+ INST_NAME - CONDITIONAL remove this flag. */
+#define COND_MASK 0xf0000000
+#define CONDITIONAL 0xe0000000
+#define PUSH_POOL 0xff000000
+
+/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */
+#define ADC_DP 0x5
+#define ADD_DP 0x4
+#define AND_DP 0x0
+#define B 0xea000000
+#define BIC_DP 0xe
+#define BL 0xeb000000
+#define BLX 0xe12fff30
+#define BX 0xe12fff10
+#define CLZ 0xe16f0f10
+#define CMP_DP 0xa
+#define BKPT 0xe1200070
+#define EOR_DP 0x1
+#define MOV_DP 0xd
+#define MUL 0xe0000090
+#define MVN_DP 0xf
+#define NOP 0xe1a00000
+#define ORR_DP 0xc
+#define PUSH 0xe92d0000
+#define POP 0xe8bd0000
+#define RSB_DP 0x3
+#define RSC_DP 0x7
+#define SBC_DP 0x6
+#define SMULL 0xe0c00090
+#define SUB_DP 0x2
+#define UMULL 0xe0800090
+#define VABS_F64 0xeeb00bc0
+#define VADD_F64 0xee300b00
+#define VCMP_F64 0xeeb40b40
+#define VDIV_F64 0xee800b00
+#define VMOV_F64 0xeeb00b40
+#define VMRS 0xeef1fa10
+#define VMUL_F64 0xee200b00
+#define VNEG_F64 0xeeb10b40
+#define VSTR 0xed000b00
+#define VSUB_F64 0xee300b40
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+/* Arm v7 specific instructions. */
+#define MOVW 0xe3000000
+#define MOVT 0xe3400000
+#define SXTB 0xe6af0070
+#define SXTH 0xe6bf0070
+#define UXTB 0xe6ef0070
+#define UXTH 0xe6ff0070
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+static int push_cpool(struct sljit_compiler *compiler)
+{
+ /* Pushing the constant pool into the instruction stream. */
+ sljit_uw* inst;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ int i;
+
+ /* The label could point the address after the constant pool. */
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;
+
+ SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0xff000000 | compiler->cpool_fill;
+
+ for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0;
+ }
+
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ while (cpool_ptr < cpool_end) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = *cpool_ptr++;
+ }
+ compiler->cpool_diff = CONST_POOL_EMPTY;
+ compiler->cpool_fill = 0;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ sljit_uw cpool_index = CPOOL_SIZE;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ sljit_ub* cpool_unique_ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+ else if (compiler->cpool_fill > 0) {
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ cpool_unique_ptr = compiler->cpool_unique;
+ do {
+ if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {
+ cpool_index = cpool_ptr - compiler->cpool;
+ break;
+ }
+ cpool_ptr++;
+ cpool_unique_ptr++;
+ } while (cpool_ptr < cpool_end);
+ }
+
+ if (cpool_index == CPOOL_SIZE) {
+ /* Must allocate a new entry in the literal pool. */
+ if (compiler->cpool_fill < CPOOL_SIZE) {
+ cpool_index = compiler->cpool_fill;
+ compiler->cpool_fill++;
+ }
+ else {
+ FAIL_IF(push_cpool(compiler));
+ cpool_index = 0;
+ compiler->cpool_fill = 1;
+ }
+ }
+
+ SLJIT_ASSERT((inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | cpool_index;
+
+ compiler->cpool[cpool_index] = literal;
+ compiler->cpool_unique[cpool_index] = 0;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))
+ FAIL_IF(push_cpool(compiler));
+
+ SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | compiler->cpool_fill;
+
+ compiler->cpool[compiler->cpool_fill] = literal;
+ compiler->cpool_unique[compiler->cpool_fill] = 1;
+ compiler->cpool_fill++;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler)
+{
+ /* Place for at least two instruction (doesn't matter whether the first has a literal). */
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))
+ return push_cpool(compiler);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler)
+{
+ /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
+ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
+ return push_inst(compiler, BLX | RM(TMP_REG1));
+}
+
+static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)
+{
+ sljit_uw diff;
+ sljit_uw ind;
+ sljit_uw counter = 0;
+ sljit_uw* clear_const_pool = const_pool;
+ sljit_uw* clear_const_pool_end = const_pool + cpool_size;
+
+ SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);
+ /* Set unused flag for all literals in the constant pool.
+ I.e.: unused literals can belong to branches, which can be encoded as B or BL.
+ We can "compress" the constant pool by discarding these literals. */
+ while (clear_const_pool < clear_const_pool_end)
+ *clear_const_pool++ = (sljit_uw)(-1);
+
+ while (last_pc_patch < code_ptr) {
+ /* Data transfer instruction with Rn == r15. */
+ if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) {
+ diff = const_pool - last_pc_patch;
+ ind = (*last_pc_patch) & 0xfff;
+
+ /* Must be a load instruction with immediate offset. */
+ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));
+ if ((int)const_pool[ind] < 0) {
+ const_pool[ind] = counter;
+ ind = counter;
+ counter++;
+ }
+ else
+ ind = const_pool[ind];
+
+ SLJIT_ASSERT(diff >= 1);
+ if (diff >= 2 || ind > 0) {
+ diff = (diff + ind - 2) << 2;
+ SLJIT_ASSERT(diff <= 0xfff);
+ *last_pc_patch = (*last_pc_patch & ~0xfff) | diff;
+ }
+ else
+ *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004;
+ }
+ last_pc_patch++;
+ }
+ return counter;
+}
+
+/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */
+struct future_patch {
+ struct future_patch* next;
+ int index;
+ int value;
+};
+
+static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
+{
+ int value;
+ struct future_patch *curr_patch, *prev_patch;
+
+ /* Using the values generated by patch_pc_relative_loads. */
+ if (!*first_patch)
+ value = (int)cpool_start_address[cpool_current_index];
+ else {
+ curr_patch = *first_patch;
+ prev_patch = 0;
+ while (1) {
+ if (!curr_patch) {
+ value = (int)cpool_start_address[cpool_current_index];
+ break;
+ }
+ if ((sljit_uw)curr_patch->index == cpool_current_index) {
+ value = curr_patch->value;
+ if (prev_patch)
+ prev_patch->next = curr_patch->next;
+ else
+ *first_patch = curr_patch->next;
+ SLJIT_FREE(curr_patch);
+ break;
+ }
+ prev_patch = curr_patch;
+ curr_patch = curr_patch->next;
+ }
+ }
+
+ if (value >= 0) {
+ if ((sljit_uw)value > cpool_current_index) {
+ curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch));
+ if (!curr_patch) {
+ while (*first_patch) {
+ curr_patch = *first_patch;
+ *first_patch = (*first_patch)->next;
+ SLJIT_FREE(curr_patch);
+ }
+ return SLJIT_ERR_ALLOC_FAILED;
+ }
+ curr_patch->next = *first_patch;
+ curr_patch->index = value;
+ curr_patch->value = cpool_start_address[value];
+ *first_patch = curr_patch;
+ }
+ cpool_start_address[value] = *buf_ptr;
+ }
+ return SLJIT_SUCCESS;
+}
+
+#else
+
+static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
+ return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
+}
+
+#endif
+
+static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)
+{
+ sljit_w diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ code_ptr--;
+
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2));
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2));
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ diff >>= 2;
+ if (jump->flags & IS_BL) {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ }
+ else {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);
+ jump->flags |= PATCH_B;
+ }
+ }
+#else
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr);
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr);
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ diff >>= 2;
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ code_ptr -= 2;
+ *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw*)addr;
+ sljit_uw *inst = (sljit_uw*)ptr[0];
+ sljit_uw mov_pc = ptr[1];
+ int bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
+ sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2);
+
+ if (diff <= 0x7fffff && diff >= -0x800000) {
+ /* Turn to branch. */
+ if (!bl) {
+ inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
+ inst[1] = NOP;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ } else {
+ /* Get the position of the constant. */
+ if (mov_pc & (1 << 23))
+ ptr = inst + ((mov_pc & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != mov_pc) {
+ inst[0] = mov_pc;
+ if (!bl) {
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[1] = BLX | RM(TMP_REG1);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ }
+ *ptr = new_addr;
+ }
+#else
+ sljit_uw *inst = (sljit_uw*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+static sljit_uw get_immediate(sljit_uw imm);
+
+static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw*)addr;
+ sljit_uw *inst = (sljit_uw*)ptr[0];
+ sljit_uw ldr_literal = ptr[1];
+ sljit_uw src2;
+
+ src2 = get_immediate(new_constant);
+ if (src2) {
+ *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ src2 = get_immediate(~new_constant);
+ if (src2) {
+ *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ if (ldr_literal & (1 << 23))
+ ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != ldr_literal) {
+ *inst = ldr_literal;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ }
+ *ptr = new_constant;
+#else
+ sljit_uw *inst = (sljit_uw*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_uw *code;
+ sljit_uw *code_ptr;
+ sljit_uw *buf_ptr;
+ sljit_uw *buf_end;
+ sljit_uw size;
+ sljit_uw word_count;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw cpool_size;
+ sljit_uw cpool_skip_alignment;
+ sljit_uw cpool_current_index;
+ sljit_uw *cpool_start_address;
+ sljit_uw *last_pc_patch;
+ struct future_patch *first_patch;
+#endif
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ size = compiler->size + (compiler->patches << 1);
+ if (compiler->cpool_fill > 0)
+ size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
+#else
+ size = compiler->size;
+#endif
+ code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ cpool_size = 0;
+ cpool_skip_alignment = 0;
+ cpool_current_index = 0;
+ cpool_start_address = NULL;
+ first_patch = NULL;
+ last_pc_patch = code;
+#endif
+
+ code_ptr = code;
+ word_count = 0;
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ if (label && label->size == 0) {
+ label->addr = (sljit_uw)code;
+ label->size = 0;
+ label = label->next;
+ }
+
+ do {
+ buf_ptr = (sljit_uw*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ word_count++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (cpool_size > 0) {
+ if (cpool_skip_alignment > 0) {
+ buf_ptr++;
+ cpool_skip_alignment--;
+ }
+ else {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ if (++cpool_current_index >= cpool_size) {
+ SLJIT_ASSERT(!first_patch);
+ cpool_size = 0;
+ if (label && label->size == word_count) {
+ /* Points after the current instruction. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ }
+ }
+ }
+ else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
+#endif
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (detect_jump_type(jump, code_ptr, code))
+ code_ptr--;
+ jump->addr = (sljit_uw)code_ptr;
+#else
+ jump->addr = (sljit_uw)(code_ptr - 2);
+ if (detect_jump_type(jump, code_ptr, code))
+ code_ptr -= 2;
+#endif
+ jump = jump->next;
+ }
+ if (label && label->size == word_count) {
+ /* code_ptr can be affected above. */
+ label->addr = (sljit_uw)(code_ptr + 1);
+ label->size = (code_ptr + 1) - code;
+ label = label->next;
+ }
+ if (const_ && const_->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_->addr = (sljit_uw)code_ptr;
+#else
+ const_->addr = (sljit_uw)(code_ptr - 1);
+#endif
+ const_ = const_->next;
+ }
+ code_ptr++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ }
+ else {
+ /* Fortunately, no need to shift. */
+ cpool_size = *buf_ptr++ & ~PUSH_POOL;
+ SLJIT_ASSERT(cpool_size > 0);
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);
+ if (cpool_current_index > 0) {
+ /* Unconditional branch. */
+ *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);
+ code_ptr = cpool_start_address + cpool_current_index;
+ }
+ cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;
+ cpool_current_index = 0;
+ last_pc_patch = code_ptr;
+ }
+#endif
+ } while (buf_ptr < buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_ASSERT(cpool_size == 0);
+ if (compiler->cpool_fill > 0) {
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);
+ if (cpool_current_index > 0)
+ code_ptr = cpool_start_address + cpool_current_index;
+
+ buf_ptr = compiler->cpool;
+ buf_end = buf_ptr + compiler->cpool_fill;
+ cpool_current_index = 0;
+ while (buf_ptr < buf_end) {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ cpool_current_index++;
+ }
+ SLJIT_ASSERT(!first_patch);
+ }
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ buf_ptr = (sljit_uw*)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ if (!(jump->flags & JUMP_ADDR)) {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000);
+ *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+ }
+ else {
+ SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000);
+ *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+ }
+ }
+ else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ jump->addr = (sljit_uw)code_ptr;
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+ code_ptr += 2;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ buf_ptr--;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ jump = jump->next;
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_ = compiler->consts;
+ while (const_) {
+ buf_ptr = (sljit_uw*)const_->addr;
+ const_->addr = (sljit_uw)code_ptr;
+
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ /* Set the value again (can be a simple constant). */
+ inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0);
+ code_ptr += 2;
+
+ const_ = const_->next;
+ }
+#endif
+
+ SLJIT_ASSERT(code_ptr - code <= (int)size);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = size * sizeof(sljit_uw);
+ return code;
+}
+
+/* emit_op inp_flags.
+ WRITE_BACK must be the first, since it is a flag. */
+#define WRITE_BACK 0x01
+#define ALLOW_IMM 0x02
+#define ALLOW_INV_IMM 0x04
+#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM)
+#define ARG_TEST 0x08
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x10
+#define HALF_DATA 0x20
+#define SIGNED_DATA 0x40
+#define LOAD_DATA 0x80
+
+#define EMIT_INSTRUCTION(inst) \
+ FAIL_IF(push_inst(compiler, (inst)))
+
+/* Condition: AL. */
+#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
+ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_uw push;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ /* Push saved registers, temporary registers
+ stmdb sp!, {..., lr} */
+ push = PUSH | (1 << 14);
+ if (temporaries >= 5)
+ push |= 1 << 11;
+ if (temporaries >= 4)
+ push |= 1 << 10;
+ if (saveds >= 5)
+ push |= 1 << 8;
+ if (saveds >= 4)
+ push |= 1 << 7;
+ if (saveds >= 3)
+ push |= 1 << 6;
+ if (saveds >= 2)
+ push |= 1 << 5;
+ if (saveds >= 1)
+ push |= 1 << 4;
+ EMIT_INSTRUCTION(push);
+
+ /* Stack must be aligned to 8 bytes: */
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+ if (local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size));
+
+ if (args >= 1)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ sljit_uw pop;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
+
+ pop = POP | (1 << 15);
+ /* Push saved registers, temporary registers
+ ldmia sp!, {..., pc} */
+ if (compiler->temporaries >= 5)
+ pop |= 1 << 11;
+ if (compiler->temporaries >= 4)
+ pop |= 1 << 10;
+ if (compiler->saveds >= 5)
+ pop |= 1 << 8;
+ if (compiler->saveds >= 4)
+ pop |= 1 << 7;
+ if (compiler->saveds >= 3)
+ pop |= 1 << 6;
+ if (compiler->saveds >= 2)
+ pop |= 1 << 5;
+ if (compiler->saveds >= 1)
+ pop |= 1 << 4;
+
+ return push_inst(compiler, pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/N - word/byte/half/NOT allowed (2 bit)
+ It contans 16 items, but not all are different. */
+
+static sljit_w data_transfer_insts[16] = {
+/* s u w */ 0xe5000000 /* str */,
+/* s u b */ 0xe5400000 /* strb */,
+/* s u h */ 0xe10000b0 /* strh */,
+/* s u N */ 0x00000000 /* not allowed */,
+/* s s w */ 0xe5000000 /* str */,
+/* s s b */ 0xe5400000 /* strb */,
+/* s s h */ 0xe10000b0 /* strh */,
+/* s s N */ 0x00000000 /* not allowed */,
+
+/* l u w */ 0xe5100000 /* ldr */,
+/* l u b */ 0xe5500000 /* ldrb */,
+/* l u h */ 0xe11000b0 /* ldrh */,
+/* l u N */ 0x00000000 /* not allowed */,
+/* l s w */ 0xe5100000 /* ldr */,
+/* l s b */ 0xe11000d0 /* ldrsb */,
+/* l s h */ 0xe11000f0 /* ldrsh */,
+/* l s N */ 0x00000000 /* not allowed */,
+};
+
+#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \
+ (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2))
+/* Normal ldr/str instruction.
+ Type2: ldrsb, ldrh, ldrsh */
+#define IS_TYPE1_TRANSFER(type) \
+ (data_transfer_insts[(type) >> 4] & 0x04000000)
+#define TYPE2_TRANSFER_IMM(imm) \
+ (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
+
+/* flags: */
+ /* Arguments are swapped. */
+#define ARGS_SWAPPED 0x01
+ /* Inverted immediate. */
+#define INV_IMM 0x02
+ /* Source and destination is register. */
+#define REG_DEST 0x04
+#define REG_SOURCE 0x08
+ /* One instruction is enough. */
+#define FAST_DEST 0x10
+ /* Multiple instructions are required. */
+#define SLOW_DEST 0x20
+/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS (1 << 20)
+/* dst: reg
+ src1: reg
+ src2: reg or imm (if allowed)
+ SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */
+#define SRC2_IMM (1 << 25)
+
+#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2)))
+
+#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2))
+
+#define EMIT_SHIFT_INS_AND_RETURN(opcode) \
+ SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \
+ if (compiler->shift_imm != 0x20) { \
+ SLJIT_ASSERT(src1 == TMP_REG1); \
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
+ if (compiler->shift_imm != 0) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
+ } \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ sljit_w mul_inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP);
+
+ case SLJIT_ADDC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP);
+
+ case SLJIT_SUB:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP);
+
+ case SLJIT_SUBC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP);
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ if (SLJIT_UNLIKELY(op & SLJIT_SET_O))
+ mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12);
+ else
+ mul_inst = MUL | (reg_map[dst] << 16);
+
+ if (dst != src2)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2]));
+ else if (dst != src1)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1]));
+ else {
+ /* Rm and Rd must not be the same register. */
+ SLJIT_ASSERT(dst != TMP_REG1);
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2])));
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1]));
+ }
+
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+
+ /* We need to use TMP_REG3. */
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0));
+
+ case SLJIT_AND:
+ if (!(flags & INV_IMM))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP);
+
+ case SLJIT_OR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP);
+
+ case SLJIT_XOR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP);
+
+ case SLJIT_SHL:
+ EMIT_SHIFT_INS_AND_RETURN(0);
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT_INS_AND_RETURN(1);
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT_INS_AND_RETURN(2);
+
+ case SLJIT_MOV:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if (dst != src2) {
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (op == SLJIT_MOV_UB)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));
+ if (flags & SET_FLAGS)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM);
+ return SLJIT_SUCCESS;
+ }
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#undef EMIT_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_SHIFT_INS_AND_RETURN
+
+/* Tests whether the immediate can be stored in the 12 bit imm field.
+ Returns with 0 if not possible. */
+static sljit_uw get_immediate(sljit_uw imm)
+{
+ int rol;
+
+ if (imm <= 0xff)
+ return SRC2_IMM | imm;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol = 8;
+ }
+ else {
+ imm = (imm << 24) | (imm >> 8);
+ rol = 0;
+ }
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ return SRC2_IMM | (imm >> 24) | (rol << 8);
+ else
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive)
+{
+ sljit_uw mask;
+ sljit_uw imm1;
+ sljit_uw imm2;
+ int rol;
+
+ /* Step1: Search a zero byte (8 continous zero bit). */
+ mask = 0xff000000;
+ rol = 8;
+ while(1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = 4 + (rol >> 1);
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3) {
+ /* rol by 8. */
+ imm = (imm << 8) | (imm >> 24);
+ mask = 0xff00;
+ rol = 24;
+ while (1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = (rol >> 1) - 8;
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3)
+ return 0;
+ }
+ break;
+ }
+ }
+
+ /* The low 8 bit must be zero. */
+ SLJIT_ASSERT(!(imm & 0xff));
+
+ if (!(imm & 0xff000000)) {
+ imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
+ imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
+ }
+ else if (imm & 0xc0000000) {
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+ else {
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2));
+ return 1;
+}
+#endif
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));
+#endif
+
+ /* Create imm by 1 inst. */
+ tmp = get_immediate(imm);
+ if (tmp) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
+ return SLJIT_SUCCESS;
+ }
+
+ tmp = get_immediate(~imm);
+ if (tmp) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
+ return SLJIT_SUCCESS;
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Create imm by 2 inst. */
+ FAIL_IF(generate_int(compiler, reg, imm, 1));
+ FAIL_IF(generate_int(compiler, reg, ~imm, 0));
+
+ /* Load integer. */
+ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm);
+#else
+ return emit_imm(compiler, reg, imm);
+#endif
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw)
+{
+ sljit_uw imm;
+
+ if (arg & SLJIT_IMM) {
+ imm = get_immediate(argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm));
+ return -1;
+ }
+ imm = get_immediate(~argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm));
+ return -1;
+ }
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads/stores. */
+ if (arg & 0xf) {
+ if (!(arg & 0xf0)) {
+ if (IS_TYPE1_TRANSFER(inp_flags)) {
+ if (argw >= 0 && argw <= 0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, argw));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, -argw));
+ return -1;
+ }
+ }
+ else {
+ if (argw >= 0 && argw <= 0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw)));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ argw = -argw;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw)));
+ return -1;
+ }
+ }
+ }
+ else if ((argw & 0x3) == 0 || IS_TYPE1_TRANSFER(inp_flags)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf,
+ RM((arg >> 4) & 0xf) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)));
+ return -1;
+ }
+ }
+
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ /* Immediate caching is not supported as it would be an operation on constant arguments. */
+ if (arg & SLJIT_IMM)
+ return 0;
+
+ /* Always a simple operation. */
+ if (arg & 0xf0)
+ return 0;
+
+ if (!(arg & 0xf)) {
+ /* Immediate access. */
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+ return 0;
+ }
+
+ if (argw <= 0xfffff && argw >= -0xfffff)
+ return 0;
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM))
+ return 1;
+
+ if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+
+ return 0;
+}
+
+#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \
+ if (max_delta & 0xf00) \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \
+ else \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm))));
+
+#define TEST_WRITE_BACK() \
+ if (inp_flags & WRITE_BACK) { \
+ tmp_r = arg & 0xf; \
+ if (reg == tmp_r) { \
+ /* This can only happen for stores */ \
+ /* since ldr reg, [reg, ...]! has no meaning */ \
+ SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg))); \
+ reg = TMP_REG3; \
+ } \
+ }
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_w max_delta;
+ sljit_w sign;
+
+ if (arg & SLJIT_IMM) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ return load_immediate(compiler, reg, argw);
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
+ max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff;
+
+ if ((arg & 0xf) == SLJIT_UNUSED) {
+ /* Write back is not used. */
+ if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) {
+ if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {
+ sign = 1;
+ argw = argw - compiler->cache_argw;
+ }
+ else {
+ sign = 0;
+ argw = compiler->cache_argw - argw;
+ }
+
+ if (max_delta & 0xf00) {
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw));
+ }
+ else {
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw)));
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* With write back, we can create some sophisticated loads, but
+ it is hard to decide whether we should convert downward (0s) or upward (1s). */
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ /* Extended imm addressing for [reg+imm] format. */
+ sign = (max_delta << 8) | 0xff;
+ if (!(arg & 0xf0) && argw <= sign && argw >= -sign) {
+ TEST_WRITE_BACK();
+ if (argw >= 0) {
+ sign = 1;
+ }
+ else {
+ sign = 0;
+ argw = -argw;
+ }
+
+ /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */
+ if (max_delta & 0xf00)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00));
+ else
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00));
+
+ argw &= max_delta;
+ GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if (arg & 0xf0) {
+ SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
+ if (inp_flags & WRITE_BACK)
+ tmp_r = arg & 0xf;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = argw - compiler->cache_argw;
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = compiler->cache_argw - argw;
+ GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
+ TEST_WRITE_BACK();
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ TEST_WRITE_BACK();
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf]));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((arg & 0xf) == tmp_r) {
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+
+ /* We prefers register and simple consts. */
+ int dst_r;
+ int src1_r;
+ int src2_r = 0;
+ int sugg_src2_r = TMP_REG2;
+ int flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ /* Destination check. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3)
+ src1_r = src1;
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ flags |= ARGS_SWAPPED;
+ src1_r = src2;
+ src2 = src1;
+ src2w = src1w;
+ }
+ else {
+ if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {
+ /* The second check will generate a hit. */
+ src2_r = get_immediate(src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED;
+ src1 = src2;
+ src1w = src2w;
+ }
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_immediate(~src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED | INV_IMM;
+ src1 = src2;
+ src1w = src2w;
+ }
+ }
+ }
+
+ src1_r = 0;
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ }
+
+ /* Source 2. */
+ if (src2_r == 0) {
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ src2_r = src2;
+ flags |= REG_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else do { /* do { } while(0) is used because of breaks. */
+ if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {
+ src2_r = get_immediate(src2w);
+ if (src2_r)
+ break;
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_immediate(~src2w);
+ if (src2_r) {
+ flags |= INV_IMM;
+ break;
+ }
+ }
+ }
+
+ /* src2_r is 0. */
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ } while (0);
+ }
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero.
+ If they are zero, they must not be registers. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED));
+ flags |= ARGS_SWAPPED;
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);
+extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ EMIT_INSTRUCTION(BKPT);
+ break;
+ case SLJIT_NOP:
+ EMIT_INSTRUCTION(NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
+ | reg_map[SLJIT_TEMPORARY_REG2]);
+#else
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
+ | reg_map[TMP_REG1]);
+#endif
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ if (compiler->temporaries >= 3)
+ EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */);
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+ if (compiler->temporaries >= 3)
+ return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, SLJIT_SUB | GET_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (src2 & SLJIT_IMM) {
+ compiler->shift_imm = src2w & 0x1f;
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);
+ }
+ else {
+ compiler->shift_imm = 0x20;
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+ }
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_uw*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+/* 0 - no fpu
+ 1 - vfp */
+static int arm_fpu_type = -1;
+
+static void init_compiler()
+{
+ if (arm_fpu_type != -1)
+ return;
+
+ /* TODO: Only the OS can help to determine the correct fpu type. */
+ arm_fpu_type = 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ if (arm_fpu_type == -1)
+ init_compiler();
+ return arm_fpu_type;
+}
+
+#else
+
+#define arm_fpu_type 1
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+#endif
+
+#define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \
+ (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs))
+#define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \
+ ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16))
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) {
+ if (argw >= 0 && argw <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw < 0 && argw >= -0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw >= 0 && argw <= 0x3ffff) {
+ SLJIT_ASSERT(get_immediate(argw & 0x3fc00));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));
+ argw &= 0x3ff;
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw < 0 && argw >= -0x3ffff) {
+ argw = -argw;
+ SLJIT_ASSERT(get_immediate(argw & 0x3fc00));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));
+ argw &= 0x3ff;
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ if (arg & 0xf0) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0));
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) {
+ if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ if (arg & 0xf) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & 0xf, reg_map[TMP_REG1]));
+ }
+ else
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_freg;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+ EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src);
+ EMIT_INSTRUCTION(VMRS);
+ return SLJIT_SUCCESS;
+ }
+
+ dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_freg, 1, src, srcw));
+ src = dst_freg;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_freg && dst_freg != TMP_FREG1)
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_freg, src, 0));
+ break;
+ case SLJIT_FNEG:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_freg, src, 0));
+ break;
+ case SLJIT_FABS:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_freg, src, 0));
+ break;
+ }
+
+ if (dst_freg == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_freg;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FSUB:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FMUL:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FDIV:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_freg, src2, src1));
+ break;
+ }
+
+ if (dst_freg == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3)));
+ else if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw))
+ return compiler->error;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3)));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src)));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2)));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst(compiler, BLX | RM(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x00000000;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x10000000;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x30000000;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x20000000;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x80000000;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x90000000;
+
+ case SLJIT_C_SIG_LESS:
+ return 0xb0000000;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0xa0000000;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0xc0000000;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0xd0000000;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_FLOAT_NAN:
+ return 0x60000000;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x70000000;
+
+ default: /* SLJIT_JUMP */
+ return 0xe0000000;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ PTR_FAIL_IF(prepare_blx(compiler));
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0,
+ type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0));
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+ jump->addr = compiler->size;
+ compiler->patches++;
+ }
+
+ if (type >= SLJIT_FAST_CALL) {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_blx(compiler));
+ }
+
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ jump->addr = compiler->size;
+#else
+ if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));
+ jump->addr = compiler->size;
+#endif
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(prepare_blx(compiler));
+ FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(emit_blx(compiler));
+#else
+ FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
+#endif
+ jump->addr = compiler->size;
+ }
+ else {
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));
+
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int reg;
+ sljit_uw cc;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ cc = get_cc(type);
+ if (GET_OPCODE(op) == SLJIT_OR) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ORR_DP, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc);
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst)));
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0));
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw);
+ }
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0));
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc);
+
+ if (reg == TMP_REG2)
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value));
+ compiler->patches++;
+#else
+ PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
+#endif
+ set_const(const_, compiler);
+
+ if (reg == TMP_REG2 && dst != SLJIT_UNUSED)
+ if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0))
+ return NULL;
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ inline_set_jump_addr(addr, new_addr, 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ inline_set_const(addr, new_constant, 1);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c b/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c
new file mode 100644
index 0000000000..c0cc8b58bb
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c
@@ -0,0 +1,405 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* mips 32-bit arch dependent functions. */
+
+static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)
+{
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ if (imm < 0 && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
+}
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
+ }
+
+#define EMIT_SHIFT(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
+ }
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, sljit_w src2)
+{
+ int overflow_ra = 0;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ }
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG));
+ }
+ }
+ else {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else if (src2 != dst)
+ overflow_ra = DR(src2);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ }
+ }
+
+ /* a + b >= a | b (otherwise, the carry should be set to 1). */
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_O)
+ return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADDC:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+ }
+ }
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+
+ FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ if (!(op & SLJIT_SET_C))
+ return SLJIT_SUCCESS;
+
+ /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
+ FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2));
+ FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
+ /* Set carry flag. */
+ return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
+
+ case SLJIT_SUB:
+ if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_U | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_U)
+ FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
+ if (op & SLJIT_SET_S) {
+ FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
+ FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SUBC:
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1));
+
+ FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG));
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & SRC2_IMM));
+ if (!(op & SLJIT_SET_O)) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
+#endif
+ }
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+ FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
+ return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+
+ case SLJIT_AND:
+ EMIT_LOGICAL(ANDI, AND);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_OR:
+ EMIT_LOGICAL(ORI, OR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_XOR:
+ EMIT_LOGICAL(XORI, XOR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SHL:
+ EMIT_SHIFT(SLL, SLLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT(SRL, SRLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT(SRA, SRAV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
+#else
+ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
+ FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
+ return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
+ }
+ /* Nearly all instructions are unmovable in the following sequence. */
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ /* Check zero. */
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
+ /* Check sign bit. */
+ FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS));
+ /* Loop for searching the highest bit. */
+ FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS));
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
+#endif
+ return SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg)));
+ return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
new file mode 100644
index 0000000000..3c6ee663e1
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
@@ -0,0 +1,1829 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "MIPS" SLJIT_CPUINFO;
+}
+
+/* Latest MIPS architecture. */
+/* Detect SLJIT_MIPS_32_64 */
+
+/* Length of an instruction word
+ Both for mips-32 and mips-64 */
+typedef sljit_ui sljit_ins;
+
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 4)
+
+/* For position independent code, t9 must contain the function address. */
+#define PIC_ADDR_REG TMP_REG2
+
+/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */
+#define TMP_EREG1 15
+#define TMP_EREG2 24
+/* Floating point status register. */
+#define FCSR_REG 31
+/* Return address register. */
+#define RETURN_ADDR_REG 31
+
+/* Flags are keept in volatile registers. */
+#define EQUAL_FLAG 7
+/* And carry flag as well. */
+#define ULESS_FLAG 10
+#define UGREATER_FLAG 11
+#define LESS_FLAG 12
+#define GREATER_FLAG 13
+#define OVERFLOW_FLAG 14
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define S(s) (reg_map[s] << 21)
+#define T(t) (reg_map[t] << 16)
+#define D(d) (reg_map[d] << 11)
+/* Absolute registers. */
+#define SA(s) ((s) << 21)
+#define TA(t) ((t) << 16)
+#define DA(d) ((d) << 11)
+#define FT(t) ((t) << (16 + 1))
+#define FS(s) ((s) << (11 + 1))
+#define FD(d) ((d) << (6 + 1))
+#define IMM(imm) ((imm) & 0xffff)
+#define SH_IMM(imm) ((imm & 0x1f) << 6)
+
+#define DR(dr) (reg_map[dr])
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) (opcode)
+#define FMT_D (17 << 21)
+
+#define ABS_D (HI(17) | FMT_D | LO(5))
+#define ADD_D (HI(17) | FMT_D | LO(0))
+#define ADDU (HI(0) | LO(33))
+#define ADDIU (HI(9))
+#define AND (HI(0) | LO(36))
+#define ANDI (HI(12))
+#define B (HI(4))
+#define BAL (HI(1) | (17 << 16))
+#define BC1F (HI(17) | (8 << 21))
+#define BC1T (HI(17) | (8 << 21) | (1 << 16))
+#define BEQ (HI(4))
+#define BGEZ (HI(1) | (1 << 16))
+#define BGTZ (HI(7))
+#define BLEZ (HI(6))
+#define BLTZ (HI(1) | (0 << 16))
+#define BNE (HI(5))
+#define BREAK (HI(0) | LO(13))
+#define C_UN_D (HI(17) | FMT_D | LO(49))
+#define C_UEQ_D (HI(17) | FMT_D | LO(51))
+#define C_ULE_D (HI(17) | FMT_D | LO(55))
+#define C_ULT_D (HI(17) | FMT_D | LO(53))
+#define DIV (HI(0) | LO(26))
+#define DIVU (HI(0) | LO(27))
+#define DIV_D (HI(17) | FMT_D | LO(3))
+#define J (HI(2))
+#define JAL (HI(3))
+#define JALR (HI(0) | LO(9))
+#define JR (HI(0) | LO(8))
+#define LD (HI(55))
+#define LDC1 (HI(53))
+#define LUI (HI(15))
+#define LW (HI(35))
+#define NEG_D (HI(17) | FMT_D | LO(7))
+#define MFHI (HI(0) | LO(16))
+#define MFLO (HI(0) | LO(18))
+#define MOV_D (HI(17) | FMT_D | LO(6))
+#define CFC1 (HI(17) | (2 << 21))
+#define MOVN (HI(0) | LO(11))
+#define MOVZ (HI(0) | LO(10))
+#define MUL_D (HI(17) | FMT_D | LO(2))
+#define MULT (HI(0) | LO(24))
+#define MULTU (HI(0) | LO(25))
+#define NOP (HI(0) | LO(0))
+#define NOR (HI(0) | LO(39))
+#define OR (HI(0) | LO(37))
+#define ORI (HI(13))
+#define SD (HI(63))
+#define SDC1 (HI(61))
+#define SLT (HI(0) | LO(42))
+#define SLTI (HI(10))
+#define SLTIU (HI(11))
+#define SLTU (HI(0) | LO(43))
+#define SLL (HI(0) | LO(0))
+#define SLLV (HI(0) | LO(4))
+#define SRL (HI(0) | LO(2))
+#define SRLV (HI(0) | LO(6))
+#define SRA (HI(0) | LO(3))
+#define SRAV (HI(0) | LO(7))
+#define SUB_D (HI(17) | FMT_D | LO(1))
+#define SUBU (HI(0) | LO(35))
+#define SW (HI(43))
+#define XOR (HI(0) | LO(38))
+#define XORI (HI(14))
+
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+#define CLZ (HI(28) | LO(32))
+#define MUL (HI(28) | LO(2))
+#define SEB (HI(31) | (16 << 6) | LO(32))
+#define SEH (HI(31) | (24 << 6) | LO(32))
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ADDU_W ADDU
+#define ADDIU_W ADDIU
+#define SLL_W SLL
+#define SUBU_W SUBU
+#else
+#define ADDU_W DADDU
+#define ADDIU_W DADDIU
+#define SLL_W DSLL
+#define SUBU_W DSUBU
+#endif
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
+ 0, 2, 5, 6, 3, 8, 17, 18, 19, 20, 21, 16, 4, 25, 9, 29
+};
+
+/* dest_reg is the absolute name of the register
+ Useful for reordering instructions in the delay slot. */
+static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ compiler->delay_slot = delay_slot;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_ins invert_branch(int flags)
+{
+ return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
+}
+
+static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+{
+ sljit_w diff;
+ sljit_uw target_addr;
+ sljit_ins *inst;
+ sljit_ins saved_inst;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return code_ptr;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size);
+ }
+ inst = (sljit_ins*)jump->addr;
+ if (jump->flags & IS_COND)
+ inst--;
+
+ /* B instructions. */
+ if (jump->flags & IS_MOVABLE) {
+ diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ saved_inst = inst[0];
+ inst[0] = inst[-1];
+ inst[-1] = saved_inst ^ invert_branch(jump->flags);
+ jump->addr -= 2 * sizeof(sljit_ins);
+ return inst;
+ }
+ }
+
+ diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = (jump->flags & IS_JAL) ? BAL : B;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+ inst[0] = inst[0] ^ invert_branch(jump->flags);
+ inst[1] = NOP;
+ jump->addr -= sizeof(sljit_ins);
+ return inst + 1;
+ }
+
+ if (jump->flags & IS_COND) {
+ if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (inst[0] & 0xffff0000) | 3;
+ inst[1] = NOP;
+ inst[2] = J;
+ inst[3] = NOP;
+ jump->addr += sizeof(sljit_ins);
+ return inst + 3;
+ }
+ return code_ptr;
+ }
+
+ /* J instuctions. */
+ if (jump->flags & IS_MOVABLE) {
+ if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ }
+
+ if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (jump->flags & IS_JAL) ? JAL : J;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+
+ return code_ptr;
+}
+
+#ifdef __GNUC__
+static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
+{
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ code_ptr = optimize_jump(jump, code_ptr, code);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins*)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2;
+ SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
+ break;
+ }
+ if (jump->flags & PATCH_J) {
+ SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff));
+ buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
+ break;
+ }
+
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_ins);
+#ifndef __GNUC__
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+#else
+ /* GCC workaround for invalid code generation with -O2. */
+ sljit_cache_flush(code, code_ptr);
+#endif
+ return code;
+}
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x01
+#define HALF_DATA 0x02
+#define INT_DATA 0x03
+#define SIGNED_DATA 0x04
+#define LOAD_DATA 0x08
+
+#define MEM_MASK 0x0f
+
+#define WRITE_BACK 0x00010
+#define ARG_TEST 0x00020
+#define CUMULATIVE_OP 0x00040
+#define LOGICAL_OP 0x00080
+#define IMM_OP 0x00100
+#define SRC2_IMM 0x00200
+
+#define UNUSED_DEST 0x00400
+#define REG_DEST 0x00800
+#define REG1_SOURCE 0x01000
+#define REG2_SOURCE 0x02000
+#define SLOW_SRC1 0x04000
+#define SLOW_SRC2 0x08000
+#define SLOW_DEST 0x10000
+
+/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */
+#define CHECK_FLAGS(list) \
+ (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#include "sljitNativeMIPS_32.c"
+#else
+#include "sljitNativeMIPS_64.c"
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define STACK_STORE SW
+#define STACK_LOAD LW
+#else
+#define STACK_STORE SD
+#define STACK_LOAD LD
+#endif
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ins base;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ local_size = (local_size + 15) & ~0xf;
+ compiler->local_size = local_size;
+
+ if (local_size <= SIMM_MAX) {
+ /* Frequent case. */
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(-local_size), DR(REAL_STACK_PTR)));
+ base = S(REAL_STACK_PTR);
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(REAL_STACK_PTR) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ FAIL_IF(push_inst(compiler, SUBU_W | S(REAL_STACK_PTR) | T(TMP_REG1) | D(REAL_STACK_PTR), DR(REAL_STACK_PTR)));
+ base = S(TMP_REG2);
+ local_size = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), MOVABLE_INS));
+
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(SLJIT_LOCALS_REG) | IMM(4 * sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ compiler->local_size = (local_size + 15) & ~0xf;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int local_size;
+ sljit_ins base;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ local_size = compiler->local_size;
+ if (local_size <= SIMM_MAX)
+ base = S(REAL_STACK_PTR);
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(REAL_STACK_PTR) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1)));
+ base = S(TMP_REG1);
+ local_size = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG));
+ if (compiler->saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2)));
+ if (compiler->saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1)));
+ if (compiler->saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3)));
+ if (compiler->saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2)));
+ if (compiler->saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1)));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ if (compiler->local_size <= SIMM_MAX)
+ return push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(compiler->local_size), UNMOVABLE_INS);
+ else
+ return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(REAL_STACK_PTR), UNMOVABLE_INS);
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ARCH_DEPEND(a, b) a
+#else
+#define ARCH_DEPEND(a, b) b
+#endif
+
+static SLJIT_CONST sljit_ins data_transfer_insts[16] = {
+/* s u w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */),
+/* s u b */ HI(40) /* sb */,
+/* s u h */ HI(41) /* sh*/,
+/* s u i */ HI(43) /* sw */,
+
+/* s s w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */),
+/* s s b */ HI(40) /* sb */,
+/* s s h */ HI(41) /* sh*/,
+/* s s i */ HI(43) /* sw */,
+
+/* l u w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */),
+/* l u b */ HI(36) /* lbu */,
+/* l u h */ HI(37) /* lhu */,
+/* l u i */ ARCH_DEPEND(HI(35) /* lw */, HI(39) /* lwu */),
+
+/* l s w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */),
+/* l s b */ HI(32) /* lb */,
+/* l s h */ HI(33) /* lh */,
+/* l s i */ HI(35) /* lw */,
+};
+
+/* reg_ar is an absoulute register! */
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ /* Works for both absoulte and relative addresses. */
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) | TA(reg_ar) | IMM(argw), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS));
+ return -1;
+ }
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ if (!(next_arg & SLJIT_MEM))
+ return 0;
+
+ /* Simple operation except for updates. */
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ next_argw &= 0x3;
+ if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0)))
+ return 1;
+ return 0;
+ }
+
+ if (arg == next_arg) {
+ if (((sljit_uw)(next_argw - argw) <= SIMM_MAX && (sljit_uw)(next_argw - argw) >= SIMM_MIN))
+ return 1;
+ return 0;
+ }
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_ar;
+ int base;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_ar = (flags & LOAD_DATA) ? reg_ar : DR(TMP_REG3);
+ base = arg & 0xf;
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ if ((flags & WRITE_BACK) && reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ /* Using the cache. */
+ if (argw == compiler->cache_argw) {
+ if (!(flags & WRITE_BACK)) {
+ if (arg == compiler->cache_arg)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ }
+ else {
+ if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) {
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ }
+ }
+
+ if (SLJIT_UNLIKELY(argw)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & 0xf0);
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
+ }
+
+ if (!(flags & WRITE_BACK)) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ tmp_ar = DR(TMP_REG3);
+ }
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
+ /* Update only applies if a base register exists. */
+ if (reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS));
+ if (argw)
+ return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base));
+ return SLJIT_SUCCESS;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)));
+ }
+ else {
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ }
+ compiler->cache_argw = argw;
+
+ if (!base)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+
+ if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
+ compiler->cache_arg = arg;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+}
+
+static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw)
+{
+ if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ int dst_r = TMP_REG2;
+ int src1_r;
+ sljit_w src2_r = 0;
+ int sugg_src2_r = TMP_REG2;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ if (GET_FLAGS(op))
+ flags |= UNUSED_DEST;
+ }
+ else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (flags & IMM_OP) {
+ if ((src2 & SLJIT_IMM) && src2w) {
+ if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src2w;
+ }
+ }
+ if ((src1 & SLJIT_IMM) && src1w && (flags & CUMULATIVE_OP) && !(flags & SRC2_IMM)) {
+ if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src1w;
+
+ /* And swap arguments. */
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ /* src2w = src2_r unneeded. */
+ }
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src1w) {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ src1_r = TMP_REG1;
+ }
+
+ /* Source 2. */
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+ if (!(flags & SRC2_IMM)) {
+ if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) {
+ FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
+ src2_r = sugg_src2_r;
+ }
+ else
+ src2_r = 0;
+ }
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ src2_r = sugg_src2_r;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ SLJIT_ASSERT(src2_r == TMP_REG2);
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst(compiler, BREAK, UNMOVABLE_INS);
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
+ return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+#if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+#endif
+ FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
+ return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define inp_flags 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), inp_flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #undef inp_flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define inp_flags 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x1f;
+#else
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x3f;
+#endif
+ return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #undef inp_flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+#if (defined SLJIT_QEMU && SLJIT_QEMU)
+ /* Qemu says fir is 0 by default. */
+ return 1;
+#elif defined(__GNUC__)
+ sljit_w fir;
+ asm ("cfc1 %0, $0" : "=r"(fir));
+ return (fir >> 22) & 0x1;
+#else
+#error "FIR check is not implemented for this architecture"
+#endif
+}
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ int hi_reg;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (!(arg & 0xf0)) {
+ /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(arg & 0xf) | FT(fpu_reg) | IMM(argw), MOVABLE_INS);
+ }
+
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ hi_reg = (arg >> 4) & 0xf;
+ if (argw) {
+ FAIL_IF(push_inst(compiler, SLL_W | T(hi_reg) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
+ hi_reg = TMP_REG1;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(hi_reg) | T(arg & 0xf) | D(TMP_REG1), DR(TMP_REG1)));
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG1) | FT(fpu_reg) | IMM(0), MOVABLE_INS);
+ }
+
+ /* Use cache. */
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(argw - compiler->cache_argw), MOVABLE_INS);
+
+ /* Put value to cache. */
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ if (arg & 0xf)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(arg & 0xf) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(0), MOVABLE_INS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+
+ /* src and dst are swapped. */
+ if (op & SLJIT_SET_E) {
+ FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG));
+ }
+ if (op & SLJIT_SET_S) {
+ /* Mixing the instructions for the two checks. */
+ FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG));
+ }
+ return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC);
+ }
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw));
+ src = dst_fr;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_fr && dst_fr != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ compiler->local_size = (local_size + 15) & ~0xf;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
+ else if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ compiler->delay_slot = UNMOVABLE_INS;
+ return label;
+}
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define JUMP_LENGTH 4
+#else
+#define JUMP_LENGTH 7
+#endif
+
+#define BR_Z(src) \
+ inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_NZ(src) \
+ inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_T() \
+ inst = BC1T | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+#define BR_F() \
+ inst = BC1F | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ int flags = 0;
+ int delay_check = UNMOVABLE_INS;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ BR_NZ(EQUAL_FLAG);
+ break;
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ BR_Z(EQUAL_FLAG);
+ break;
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ BR_Z(ULESS_FLAG);
+ break;
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ BR_NZ(ULESS_FLAG);
+ break;
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ BR_Z(UGREATER_FLAG);
+ break;
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ BR_NZ(UGREATER_FLAG);
+ break;
+ case SLJIT_C_SIG_LESS:
+ BR_Z(LESS_FLAG);
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ BR_NZ(LESS_FLAG);
+ break;
+ case SLJIT_C_SIG_GREATER:
+ BR_Z(GREATER_FLAG);
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ BR_NZ(GREATER_FLAG);
+ break;
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ BR_Z(OVERFLOW_FLAG);
+ break;
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ BR_NZ(OVERFLOW_FLAG);
+ break;
+ case SLJIT_C_FLOAT_NAN:
+ BR_F();
+ break;
+ case SLJIT_C_FLOAT_NOT_NAN:
+ BR_T();
+ break;
+ default:
+ /* Not conditional branch. */
+ inst = 0;
+ break;
+ }
+
+ jump->flags |= flags;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
+ jump->flags |= IS_MOVABLE;
+
+ if (inst)
+ PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ if (type <= SLJIT_JUMP) {
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ } else {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ /* Cannot be optimized out if type is >= CALL0. */
+ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
+ PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ /* A NOP if type < CALL1. */
+ PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS));
+ }
+ return jump;
+}
+
+#define RESOLVE_IMM1() \
+ if (src1 & SLJIT_IMM) { \
+ if (src1w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
+ src1 = TMP_REG1; \
+ } \
+ else \
+ src1 = 0; \
+ }
+
+#define RESOLVE_IMM2() \
+ if (src2 & SLJIT_IMM) { \
+ if (src2w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
+ src2 = TMP_REG2; \
+ } \
+ else \
+ src2 = 0; \
+ }
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ struct sljit_jump *jump;
+ int flags;
+ sljit_ins inst;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA;
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, DR(TMP_REG1), src1, src1w))
+ PTR_FAIL_IF(compiler->error);
+ else
+ PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
+ src1 = TMP_REG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, DR(TMP_REG2), src2, src2w))
+ PTR_FAIL_IF(compiler->error);
+ else
+ PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
+ src2 = TMP_REG2;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type <= SLJIT_C_NOT_EQUAL) {
+ RESOLVE_IMM1();
+ RESOLVE_IMM2();
+ jump->flags |= IS_BIT26_COND;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
+ jump->flags |= IS_MOVABLE;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else if (type >= SLJIT_C_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
+ inst = NOP;
+ if ((src1 & SLJIT_IMM) && (src1w == 0)) {
+ RESOLVE_IMM2();
+ switch (type) {
+ case SLJIT_C_SIG_LESS:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ }
+ src1 = src2;
+ }
+ else {
+ RESOLVE_IMM1();
+ switch (type) {
+ case SLJIT_C_SIG_LESS:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ }
+ }
+ PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else {
+ if (type == SLJIT_C_LESS || type == SLJIT_C_GREATER_EQUAL || type == SLJIT_C_SIG_LESS || type == SLJIT_C_SIG_GREATER_EQUAL) {
+ RESOLVE_IMM1();
+ if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM2();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_C_LESS || type == SLJIT_C_SIG_LESS) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL;
+ }
+ else {
+ RESOLVE_IMM2();
+ if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM1();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_C_GREATER || type == SLJIT_C_SIG_GREATER) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL;
+ }
+
+ jump->flags |= IS_BIT26_COND;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef RESOLVE_IMM1
+#undef RESOLVE_IMM2
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ int if_true;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+ if (src2 > SLJIT_FLOAT_REG4) {
+ PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->flags |= IS_BIT16_COND;
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_C_FLOAT_EQUAL:
+ inst = C_UEQ_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ inst = C_UEQ_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_LESS:
+ inst = C_ULT_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ inst = C_ULT_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_GREATER:
+ inst = C_ULE_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ inst = C_ULE_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NAN:
+ inst = C_UN_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NOT_NAN:
+ default: /* Make compilers happy. */
+ inst = C_UN_D;
+ if_true = 0;
+ break;
+ }
+
+ PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS));
+ /* Intentionally the other opcode. */
+ PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS));
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef JUMP_LENGTH
+#undef BR_Z
+#undef BR_NZ
+#undef BR_T
+#undef BR_F
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ int src_r = TMP_REG2;
+ struct sljit_jump *jump = NULL;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+ if (DR(src) != 4)
+ src_r = src;
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ }
+
+ if (type >= SLJIT_CALL0) {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ if (src & (SLJIT_IMM | SLJIT_MEM)) {
+ if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
+ else {
+ SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ }
+ FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ /* We need an extra instruction in any case. */
+ return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS);
+ }
+
+ /* Register input. */
+ if (type >= SLJIT_CALL1)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4));
+ FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS);
+ }
+
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
+ jump->u.target = srcw;
+
+ if (compiler->delay_slot != UNMOVABLE_INS)
+ jump->flags |= IS_MOVABLE;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ }
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS));
+ if (jump)
+ jump->addr = compiler->size;
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int sugg_dst_ar, dst_ar;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2);
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_NOT_EQUAL:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+ case SLJIT_C_LESS:
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_LESS:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ dst_ar = ULESS_FLAG;
+ break;
+ case SLJIT_C_GREATER:
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_GREATER:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ dst_ar = UGREATER_FLAG;
+ break;
+ case SLJIT_C_SIG_LESS:
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ dst_ar = LESS_FLAG;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ case SLJIT_C_SIG_LESS_EQUAL:
+ dst_ar = GREATER_FLAG;
+ break;
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_NOT_OVERFLOW:
+ dst_ar = OVERFLOW_FLAG;
+ break;
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ type ^= 0x1; /* Flip type bit for the XORI below. */
+ break;
+ case SLJIT_C_FLOAT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ dst_ar = EQUAL_FLAG;
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ dst_ar = sugg_dst_ar;
+ break;
+ }
+
+ if (type & 0x1) {
+ FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ }
+
+ if (GET_OPCODE(op) == SLJIT_OR) {
+ if (DR(TMP_REG2) != dst_ar)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0);
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
+
+ if (sugg_dst_ar != dst_ar)
+ return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_32.c b/src/3rdparty/pcre/sljit/sljitNativePPC_32.c
new file mode 100644
index 0000000000..82d0508ac1
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_32.c
@@ -0,0 +1,262 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 32-bit arch dependent functions. */
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm));
+
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+}
+
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ switch (op) {
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
+ }
+ return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_64.c b/src/3rdparty/pcre/sljit/sljitNativePPC_64.c
new file mode 100644
index 0000000000..cc2ae37eb9
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_64.c
@@ -0,0 +1,428 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 64-bit arch dependent functions. */
+
+#ifdef __GNUC__
+#define ASM_SLJIT_CLZ(src, dst) \
+ asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
+#else
+#error "Must implement count leading zeroes"
+#endif
+
+#define RLDI(dst, src, sh, mb, type) \
+ (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
+
+#define PUSH_RLDICR(reg, shift) \
+ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ sljit_uw tmp;
+ sljit_uw shift;
+ sljit_uw tmp2;
+ sljit_uw shift2;
+
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm));
+
+ if (imm <= SLJIT_W(0x7fffffff) && imm >= SLJIT_W(-0x80000000)) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+ }
+
+ /* Count leading zeroes. */
+ tmp = (imm >= 0) ? imm : ~imm;
+ ASM_SLJIT_CLZ(tmp, shift);
+ SLJIT_ASSERT(shift > 0);
+ shift--;
+ tmp = (imm << shift);
+
+ if ((tmp & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift += 15;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ if ((tmp & ~0xffffffff00000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
+ shift += 31;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ /* Cut out the 16 bit from immediate. */
+ shift += 15;
+ tmp2 = imm & ((1ul << (63 - shift)) - 1);
+
+ if (tmp2 <= 0xffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);
+ }
+
+ if (tmp2 <= 0xffffffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
+ }
+
+ ASM_SLJIT_CLZ(tmp2, shift2);
+ tmp2 <<= shift2;
+
+ if ((tmp2 & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift2 += 15;
+ shift += (63 - shift2);
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));
+ return PUSH_RLDICR(reg, shift2);
+ }
+
+ /* The general version. */
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
+}
+
+/* Simplified mnemonics: clrldi. */
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))
+
+/* Sign extension for integer operations. */
+#define UN_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ }
+
+#define BIN_EXTS() \
+ if (flags & ALT_SIGN_EXT) { \
+ if (flags & REG1_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ } \
+ if (flags & REG2_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ } \
+ }
+
+#define BIN_IMM_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ }
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ switch (op) {
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ BIN_IMM_EXTS();
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ BIN_EXTS();
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ BIN_EXTS();
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ BIN_EXTS();
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+ return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_MOV:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SI)
+ return push_inst(compiler, EXTSW | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (flags & ALT_FORM1)
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+ return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func)
+{
+ sljit_w* ptrs;
+ if (func_ptr)
+ *func_ptr = (void*)context;
+ ptrs = (sljit_w*)func;
+ context->addr = addr ? addr : ptrs[0];
+ context->r2 = ptrs[1];
+ context->r11 = ptrs[2];
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_common.c b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
new file mode 100644
index 0000000000..f0f191de1f
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
@@ -0,0 +1,1872 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "PowerPC" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word.
+ Both for ppc-32 and ppc-64. */
+typedef sljit_ui sljit_ins;
+
+static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
+{
+ while (from < to) {
+#ifdef __GNUC__
+ asm volatile ( "icbi 0, %0" : : "r"(from) );
+#else
+#error "Must implement icbi"
+#endif
+ from++;
+ }
+}
+
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define ZERO_REG (SLJIT_NO_REGISTERS + 4)
+#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 5)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+#define D(d) (reg_map[d] << 21)
+#define S(s) (reg_map[s] << 21)
+#define A(a) (reg_map[a] << 16)
+#define B(b) (reg_map[b] << 11)
+#define C(c) (reg_map[c] << 6)
+#define FD(fd) ((fd) << 21)
+#define FA(fa) ((fa) << 16)
+#define FB(fb) ((fb) << 11)
+#define FC(fc) ((fc) << 6)
+#define IMM(imm) ((imm) & 0xffff)
+#define CRD(d) ((d) << 21)
+
+/* Instruction bit sections.
+ OE and Rc flag (see ALT_SET_FLAGS). */
+#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
+/* Rc flag (see ALT_SET_FLAGS). */
+#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) ((opcode) << 1)
+
+#define ADD (HI(31) | LO(266))
+#define ADDC (HI(31) | LO(10))
+#define ADDE (HI(31) | LO(138))
+#define ADDI (HI(14))
+#define ADDIC (HI(13))
+#define ADDIS (HI(15))
+#define ADDME (HI(31) | LO(234))
+#define AND (HI(31) | LO(28))
+#define ANDI (HI(28))
+#define ANDIS (HI(29))
+#define Bx (HI(18))
+#define BCx (HI(16))
+#define BCCTR (HI(19) | LO(528) | (3 << 11))
+#define BLR (HI(19) | LO(16) | (0x14 << 21))
+#define CNTLZD (HI(31) | LO(58))
+#define CNTLZW (HI(31) | LO(26))
+#define CMP (HI(31) | LO(0))
+#define CMPI (HI(11))
+#define CMPL (HI(31) | LO(32))
+#define CMPLI (HI(10))
+#define CROR (HI(19) | LO(449))
+#define DIVD (HI(31) | LO(489))
+#define DIVDU (HI(31) | LO(457))
+#define DIVW (HI(31) | LO(491))
+#define DIVWU (HI(31) | LO(459))
+#define EXTSB (HI(31) | LO(954))
+#define EXTSH (HI(31) | LO(922))
+#define EXTSW (HI(31) | LO(986))
+#define FABS (HI(63) | LO(264))
+#define FADD (HI(63) | LO(21))
+#define FCMPU (HI(63) | LO(0))
+#define FDIV (HI(63) | LO(18))
+#define FMR (HI(63) | LO(72))
+#define FMUL (HI(63) | LO(25))
+#define FNEG (HI(63) | LO(40))
+#define FSUB (HI(63) | LO(20))
+#define LD (HI(58) | 0)
+#define LFD (HI(50))
+#define LFDUX (HI(31) | LO(631))
+#define LFDX (HI(31) | LO(599))
+#define LWZ (HI(32))
+#define MFCR (HI(31) | LO(19))
+#define MFLR (HI(31) | LO(339) | 0x80000)
+#define MFXER (HI(31) | LO(339) | 0x10000)
+#define MTCTR (HI(31) | LO(467) | 0x90000)
+#define MTLR (HI(31) | LO(467) | 0x80000)
+#define MTXER (HI(31) | LO(467) | 0x10000)
+#define MULHD (HI(31) | LO(73))
+#define MULHDU (HI(31) | LO(9))
+#define MULHW (HI(31) | LO(75))
+#define MULHWU (HI(31) | LO(11))
+#define MULLD (HI(31) | LO(233))
+#define MULLI (HI(7))
+#define MULLW (HI(31) | LO(235))
+#define NEG (HI(31) | LO(104))
+#define NOP (HI(24))
+#define NOR (HI(31) | LO(124))
+#define OR (HI(31) | LO(444))
+#define ORI (HI(24))
+#define ORIS (HI(25))
+#define RLDICL (HI(30))
+#define RLWINM (HI(21))
+#define SLD (HI(31) | LO(27))
+#define SLW (HI(31) | LO(24))
+#define SRAD (HI(31) | LO(794))
+#define SRADI (HI(31) | LO(413 << 1))
+#define SRAW (HI(31) | LO(792))
+#define SRAWI (HI(31) | LO(824))
+#define SRD (HI(31) | LO(539))
+#define SRW (HI(31) | LO(536))
+#define STD (HI(62) | 0)
+#define STDU (HI(62) | 1)
+#define STDUX (HI(31) | LO(181))
+#define STFD (HI(54))
+#define STFDUX (HI(31) | LO(759))
+#define STFDX (HI(31) | LO(727))
+#define STW (HI(36))
+#define STWU (HI(37))
+#define STWUX (HI(31) | LO(183))
+#define SUBF (HI(31) | LO(40))
+#define SUBFC (HI(31) | LO(8))
+#define SUBFE (HI(31) | LO(136))
+#define SUBFIC (HI(8))
+#define XOR (HI(31) | LO(316))
+#define XORI (HI(26))
+#define XORIS (HI(27))
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+/* SLJIT_LOCALS_REG is not the real stack register, since it must
+ point to the head of the stack chain. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
+ 0, 3, 4, 5, 6, 7, 29, 28, 27, 26, 25, 31, 8, 9, 10, 30, 1
+};
+
+static int push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+{
+ sljit_w diff;
+ sljit_uw target_addr;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size);
+ }
+ diff = ((sljit_w)target_addr - (sljit_w)(code_ptr)) & ~0x3l;
+
+ if (jump->flags & UNCOND_B) {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ if (target_addr <= 0x03ffffff) {
+ jump->flags |= PATCH_B | ABSOLUTE_B;
+ return 1;
+ }
+ }
+ else {
+ if (diff <= 0x7fff && diff >= -0x8000) {
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ if (target_addr <= 0xffff) {
+ jump->flags |= PATCH_B | ABSOLUTE_B;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#endif
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ if (optimize_jump(jump, code_ptr, code)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ code_ptr[-3] = code_ptr[0];
+ code_ptr -= 3;
+#else
+ code_ptr[-6] = code_ptr[0];
+ code_ptr -= 6;
+#endif
+ }
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size - ((compiler->size & 0x1) ? 3 : 2));
+#else
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins*)jump->addr;
+ if (jump->flags & PATCH_B) {
+ if (jump->flags & UNCOND_B) {
+ if (!(jump->flags & ABSOLUTE_B)) {
+ addr = addr - jump->addr;
+ SLJIT_ASSERT((sljit_w)addr <= 0x01ffffff && (sljit_w)addr >= -0x02000000);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
+ }
+ else {
+ SLJIT_ASSERT(addr <= 0x03ffffff);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
+ }
+ }
+ else {
+ if (!(jump->flags & ABSOLUTE_B)) {
+ addr = addr - jump->addr;
+ SLJIT_ASSERT((sljit_w)addr <= 0x7fff && (sljit_w)addr >= -0x8000);
+ *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
+ }
+ else {
+ addr = addr & ~0x3l;
+ SLJIT_ASSERT(addr <= 0xffff);
+ *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
+ }
+
+ }
+ break;
+ }
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_ins);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (((sljit_w)code_ptr) & 0x4)
+ code_ptr++;
+ sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_w)code, sljit_generate_code);
+ return code_ptr;
+#else
+ return code;
+#endif
+}
+
+/* inp_flags: */
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x01
+#define HALF_DATA 0x02
+#define INT_DATA 0x03
+#define SIGNED_DATA 0x04
+#define LOAD_DATA 0x08
+#define WRITE_BACK 0x10
+#define INDEXED 0x20
+
+#define MEM_MASK 0x3f
+
+/* Other inp_flags. */
+
+#define ARG_TEST 0x000100
+/* Integer opertion and set flags -> requires exts on 64 bit systems. */
+#define ALT_SIGN_EXT 0x000200
+/* This flag affects the RC() and OERC() macros. */
+#define ALT_SET_FLAGS 0x000400
+#define ALT_FORM1 0x010000
+#define ALT_FORM2 0x020000
+#define ALT_FORM3 0x040000
+#define ALT_FORM4 0x080000
+#define ALT_FORM5 0x100000
+#define ALT_FORM6 0x200000
+
+/* Source and destination is register. */
+#define REG_DEST 0x000001
+#define REG1_SOURCE 0x000002
+#define REG2_SOURCE 0x000004
+/* getput_arg_fast returned true. */
+#define FAST_DEST 0x000008
+/* Multiple instructions are required. */
+#define SLOW_DEST 0x000010
+/*
+ALT_SIGN_EXT 0x000200
+ALT_SET_FLAGS 0x000400
+ALT_FORM1 0x010000
+...
+ALT_FORM6 0x200000 */
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#include "sljitNativePPC_32.c"
+#else
+#include "sljitNativePPC_64.c"
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define STACK_STORE STW
+#define STACK_LOAD LWZ
+#else
+#define STACK_STORE STD
+#define STACK_LOAD LD
+#endif
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->has_locals = local_size > 0;
+
+ FAIL_IF(push_inst(compiler, MFLR | D(0)));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(-(int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(REAL_STACK_PTR) | IMM(-2 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(REAL_STACK_PTR) | IMM(-3 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(REAL_STACK_PTR) | IMM(-4 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(REAL_STACK_PTR) | IMM(-5 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(REAL_STACK_PTR) | IMM(-6 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(REAL_STACK_PTR) | IMM(-7 * (int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(REAL_STACK_PTR) | IMM(sizeof(sljit_w)) ));
+
+ FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0));
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3)));
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STWU | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(-compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
+ FAIL_IF(push_inst(compiler, STWUX | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(2 * sizeof(sljit_w))));
+#else
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STDU | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(-compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
+ FAIL_IF(push_inst(compiler, STDUX | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM((7 + 8) * sizeof(sljit_w))));
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, ADDI | D(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
+ FAIL_IF(push_inst(compiler, ADD | D(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(REAL_STACK_PTR) | IMM(sizeof(sljit_w))));
+ if (compiler->saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(REAL_STACK_PTR) | IMM(-7 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(REAL_STACK_PTR) | IMM(-6 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(REAL_STACK_PTR) | IMM(-5 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(REAL_STACK_PTR) | IMM(-4 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(REAL_STACK_PTR) | IMM(-3 * (int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(REAL_STACK_PTR) | IMM(-2 * (int)(sizeof(sljit_w))) ));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(-(int)(sizeof(sljit_w))) ));
+
+ FAIL_IF(push_inst(compiler, MTLR | S(0)));
+ FAIL_IF(push_inst(compiler, BLR));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* i/x - immediate/indexed form
+ n/w - no write-back / write-back (1 bit)
+ s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/i - word/byte/half/int allowed (2 bit)
+ It contans 32 items, but not all are different. */
+
+/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
+#define ADDR_MODE2 0x10000
+/* 64-bit only: there is no lwau instruction. */
+#define UPDATE_REQ 0x20000
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define ARCH_DEPEND(a, b) a
+#define GET_INST_CODE(inst) (inst)
+#else
+#define ARCH_DEPEND(a, b) b
+#define GET_INST_CODE(index) ((inst) & ~(ADDR_MODE2 | UPDATE_REQ))
+#endif
+
+static SLJIT_CONST sljit_ins data_transfer_insts[64] = {
+
+/* No write-back. */
+
+/* i n s u w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
+/* i n s u b */ HI(38) /* stb */,
+/* i n s u h */ HI(44) /* sth*/,
+/* i n s u i */ HI(36) /* stw */,
+
+/* i n s s w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
+/* i n s s b */ HI(38) /* stb */,
+/* i n s s h */ HI(44) /* sth*/,
+/* i n s s i */ HI(36) /* stw */,
+
+/* i n l u w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
+/* i n l u b */ HI(34) /* lbz */,
+/* i n l u h */ HI(40) /* lhz */,
+/* i n l u i */ HI(32) /* lwz */,
+
+/* i n l s w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
+/* i n l s b */ HI(34) /* lbz */ /* EXTS_REQ */,
+/* i n l s h */ HI(42) /* lha */,
+/* i n l s i */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */),
+
+/* Write-back. */
+
+/* i w s u w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
+/* i w s u b */ HI(39) /* stbu */,
+/* i w s u h */ HI(45) /* sthu */,
+/* i w s u i */ HI(37) /* stwu */,
+
+/* i w s s w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
+/* i w s s b */ HI(39) /* stbu */,
+/* i w s s h */ HI(45) /* sthu */,
+/* i w s s i */ HI(37) /* stwu */,
+
+/* i w l u w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
+/* i w l u b */ HI(35) /* lbzu */,
+/* i w l u h */ HI(41) /* lhzu */,
+/* i w l u i */ HI(33) /* lwzu */,
+
+/* i w l s w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
+/* i w l s b */ HI(35) /* lbzu */ /* EXTS_REQ */,
+/* i w l s h */ HI(43) /* lhau */,
+/* i w l s i */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */),
+
+/* ---------- */
+/* Indexed */
+/* ---------- */
+
+/* No write-back. */
+
+/* x n s u w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* x n s u b */ HI(31) | LO(215) /* stbx */,
+/* x n s u h */ HI(31) | LO(407) /* sthx */,
+/* x n s u i */ HI(31) | LO(151) /* stwx */,
+
+/* x n s s w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* x n s s b */ HI(31) | LO(215) /* stbx */,
+/* x n s s h */ HI(31) | LO(407) /* sthx */,
+/* x n s s i */ HI(31) | LO(151) /* stwx */,
+
+/* x n l u w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* x n l u b */ HI(31) | LO(87) /* lbzx */,
+/* x n l u h */ HI(31) | LO(279) /* lhzx */,
+/* x n l u i */ HI(31) | LO(23) /* lwzx */,
+
+/* x n l s w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* x n l s b */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
+/* x n l s h */ HI(31) | LO(343) /* lhax */,
+/* x n l s i */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
+
+/* Write-back. */
+
+/* x w s u w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* x w s u b */ HI(31) | LO(247) /* stbux */,
+/* x w s u h */ HI(31) | LO(439) /* sthux */,
+/* x w s u i */ HI(31) | LO(183) /* stwux */,
+
+/* x w s s w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* x w s s b */ HI(31) | LO(247) /* stbux */,
+/* x w s s h */ HI(31) | LO(439) /* sthux */,
+/* x w s s i */ HI(31) | LO(183) /* stwux */,
+
+/* x w l u w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* x w l u b */ HI(31) | LO(119) /* lbzux */,
+/* x w l u h */ HI(31) | LO(311) /* lhzux */,
+/* x w l u i */ HI(31) | LO(55) /* lwzux */,
+
+/* x w l s w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* x w l s b */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
+/* x w l s h */ HI(31) | LO(375) /* lhaux */,
+/* x w l s i */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */)
+
+};
+
+#undef ARCH_DEPEND
+
+/* Simple cases, (no caching is required). */
+static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw)
+{
+ sljit_ins inst;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ int tmp_reg;
+#endif
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(arg & 0xf)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw));
+ return -1;
+ }
+#else
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN &&
+ (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw));
+ return -1;
+ }
+#endif
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ if (!(arg & 0xf0)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw));
+ return -1;
+ }
+#else
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ if ((inp_flags & WRITE_BACK) && (inst & UPDATE_REQ)) {
+ tmp_reg = (inp_flags & LOAD_DATA) ? (arg & 0xf) : TMP_REG3;
+ if (push_inst(compiler, ADDI | D(tmp_reg) | A(arg & 0xf) | IMM(argw)))
+ return -1;
+ arg = tmp_reg | SLJIT_MEM;
+ argw = 0;
+ }
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw));
+ return -1;
+ }
+#endif
+ }
+ else if (!(argw & 0x3)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B((arg >> 4) & 0xf));
+ return -1;
+ }
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those operator always
+ uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ SLJIT_ASSERT(next_arg & SLJIT_MEM);
+
+ if (!(arg & 0xf)) {
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX))
+ return 1;
+ return 0;
+ }
+
+ if (arg & 0xf0)
+ return 0;
+
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN))
+ return 1;
+ }
+
+ if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX))
+ return 1;
+
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define ADJUST_CACHED_IMM(imm) \
+ if ((inst & ADDR_MODE2) && (imm & 0x3)) { \
+ /* Adjust cached value. Fortunately this is really a rare case */ \
+ compiler->cache_argw += imm & 0x3; \
+ FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
+ imm &= ~0x3; \
+ }
+#else
+#define ADJUST_CACHED_IMM(imm)
+#endif
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_ins inst;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
+ if ((arg & 0xf) == tmp_r) {
+ /* Special case for "mov reg, [reg, ... ]".
+ Caching would not happen anyway. */
+ tmp_r = TMP_REG3;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ if (!(arg & 0xf)) {
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= SIMM_MAX || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= SIMM_MAX)) {
+ argw = argw - compiler->cache_argw;
+ ADJUST_CACHED_IMM(argw);
+ SLJIT_ASSERT(!(inst & UPDATE_REQ));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw));
+ }
+
+ if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(tmp_r));
+ }
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ /* Otherwise getput_arg_fast would capture it. */
+ SLJIT_ASSERT(argw);
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1)));
+#endif
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r));
+ }
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+
+ if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw <= SIMM_MAX || (sljit_uw)compiler->cache_argw - (sljit_uw)argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = argw - compiler->cache_argw;
+ ADJUST_CACHED_IMM(argw);
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw));
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3));
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3));
+ }
+
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & 0xf)));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3));
+ }
+
+ /* Get the indexed version instead of the normal one. */
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r));
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ int dst_r;
+ int src1_r;
+ int src2_r;
+ int sugg_src2_r = TMP_REG2;
+ int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ /* Destination check. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if ((inp_flags & 0x3) == INT_DATA) {
+ if (inp_flags & SIGNED_DATA)
+ src1w = (signed int)src1w;
+ else
+ src1w = (unsigned int)src1w;
+ }
+#endif
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1_r = TMP_REG1;
+ }
+ else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+
+ /* Source 2. */
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if ((inp_flags & 0x3) == INT_DATA) {
+ if (inp_flags & SIGNED_DATA)
+ src2w = (signed int)src2w;
+ else
+ src2w = (unsigned int)src2w;
+ }
+#endif
+ FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
+ src2_r = sugg_src2_r;
+ }
+ else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ else
+ src2_r = 0;
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed).
+ All arguments are complex addressing modes, and it is a binary operator. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_BREAKPOINT:
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2));
+#else
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2));
+#endif
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+ }
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+#else
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ if ((src & SLJIT_IMM) && srcw == 0)
+ src = ZERO_REG;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ inp_flags |= INT_DATA | SIGNED_DATA;
+ if (src & SLJIT_IMM)
+ srcw = (int)srcw;
+ }
+#endif
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, SLJIT_NOT, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_NEG, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_CLZ:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ return emit_op(compiler, SLJIT_CLZ, inp_flags | (!(op & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_CLZ, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define TEST_SL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
+
+#define TEST_UL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000))
+#else
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
+#endif
+
+#define TEST_UH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_ADD_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000))
+#else
+#define TEST_ADD_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_UI_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
+#else
+#define TEST_UI_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ if ((src1 & SLJIT_IMM) && src1w == 0)
+ src1 = ZERO_REG;
+ if ((src2 & SLJIT_IMM) && src2w == 0)
+ src2 = ZERO_REG;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ inp_flags |= INT_DATA | SIGNED_DATA;
+ if (src1 & SLJIT_IMM)
+ src1w = (src1w << 32) >> 32;
+ if (src2 & SLJIT_IMM)
+ src2w = (src2w << 32) >> 32;
+ if (GET_FLAGS(op))
+ inp_flags |= ALT_SIGN_EXT;
+ }
+#endif
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_ADD_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_ADD, inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_ADDC:
+ return emit_op(compiler, SLJIT_ADDC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, -src2w)) {
+ compiler->imm = ((-src2w) >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, -src2w)) {
+ compiler->imm = -src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
+ if (!(op & SLJIT_SET_U)) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
+ }
+ if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
+ compiler->imm = src2w;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUBC:
+ return emit_op(compiler, SLJIT_SUBC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP)
+ inp_flags |= ALT_FORM2;
+#endif
+ if (!GET_FLAGS(op)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_MUL, inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* Commutative unsigned operations. */
+ if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UL_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
+ if (TEST_UI_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UI_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP)
+ inp_flags |= ALT_FORM2;
+#endif
+ if (src2 & SLJIT_IMM) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (!(arg & 0xf0)) {
+ /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(arg & 0xf) | IMM(argw));
+ }
+
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ if (argw) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(TMP_REG2) | (argw << 11) | ((31 - argw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, (arg >> 4) & 0xf, argw, 63 - argw, 1)));
+#endif
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B(TMP_REG2));
+ }
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B((arg >> 4) & 0xf));
+ }
+
+ /* Use cache. */
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(TMP_REG3) | IMM(argw - compiler->cache_argw));
+
+ /* Put value to cache. */
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ if (!(arg & 0xf))
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(0) | B(TMP_REG3));
+ return push_inst(compiler, (load ? LFDUX : STFDUX) | FD(fpu_reg) | A(TMP_REG3) | B(arg & 0xf));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+ return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src));
+ }
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw));
+ src = dst_fr;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_fr && dst_fr != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src)));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src)));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src)));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst(compiler, FADD | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst(compiler, FSUB | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst(compiler, FMUL | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst(compiler, FDIV | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, MFLR | D(dst));
+ else if (dst & SLJIT_MEM) {
+ FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst(compiler, MTLR | S(src)));
+ else {
+ if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+ FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
+ }
+ return push_inst(compiler, BLR);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ return (12 << 21) | (2 << 16);
+
+ case SLJIT_C_NOT_EQUAL:
+ return (4 << 21) | (2 << 16);
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return (12 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return (4 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return (12 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return (4 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_C_SIG_LESS:
+ return (12 << 21) | (0 << 16);
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return (4 << 21) | (0 << 16);
+
+ case SLJIT_C_SIG_GREATER:
+ return (12 << 21) | (1 << 16);
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return (4 << 21) | (1 << 16);
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ return (12 << 21) | (3 << 16);
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ return (4 << 21) | (3 << 16);
+
+ case SLJIT_C_FLOAT_EQUAL:
+ return (12 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return (4 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_C_FLOAT_NAN:
+ return (12 << 21) | ((4 + 3) << 16);
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return (4 << 21) | ((4 + 3) << 16);
+
+ default:
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+ return (20 << 21);
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ sljit_ins bo_bi_flags;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff);
+ if (!bo_bi_flags)
+ return NULL;
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In PPC, we don't need to touch the arguments. */
+ if (type >= SLJIT_JUMP)
+ jump->flags |= UNCOND_B;
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
+ PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1)));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ sljit_ins bo_bi_flags;
+ struct sljit_jump *jump = NULL;
+ int src_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ bo_bi_flags = get_bo_bi_flags(compiler, type);
+ FAIL_IF(!bo_bi_flags);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ src_r = src;
+ else if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | UNCOND_B);
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ src_r = TMP_REG2;
+ }
+ else {
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ src_r = TMP_REG2;
+ }
+
+ FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
+ if (jump)
+ jump->addr = compiler->size;
+ return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0));
+}
+
+/* Get a bit from CR, all other bits are zeroed. */
+#define GET_CR_BIT(bit, dst) \
+ FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
+ FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
+
+#define INVERT_BIT(dst) \
+ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int reg;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ GET_CR_BIT(2, reg);
+ break;
+
+ case SLJIT_C_NOT_EQUAL:
+ GET_CR_BIT(2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ GET_CR_BIT(4 + 0, reg);
+ break;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ GET_CR_BIT(4 + 0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ GET_CR_BIT(4 + 1, reg);
+ break;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ GET_CR_BIT(4 + 1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_SIG_LESS:
+ GET_CR_BIT(0, reg);
+ break;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ GET_CR_BIT(0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_SIG_GREATER:
+ GET_CR_BIT(1, reg);
+ break;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ GET_CR_BIT(1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ break;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_FLOAT_EQUAL:
+ GET_CR_BIT(4 + 2, reg);
+ break;
+
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ GET_CR_BIT(4 + 2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ GET_CR_BIT(4 + 3, reg);
+ break;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ GET_CR_BIT(4 + 3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (GET_OPCODE(op) == SLJIT_OR)
+ return emit_op(compiler, GET_OPCODE(op), GET_FLAGS(op) ? ALT_SET_FLAGS : 0, dst, dstw, dst, dstw, TMP_REG2, 0);
+
+ if (reg == TMP_REG2)
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
new file mode 100644
index 0000000000..68bca8441a
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
@@ -0,0 +1,517 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 32-bit arch dependent functions. */
+
+static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w));
+ FAIL_IF(!buf);
+ INC_SIZE(1 + sizeof(sljit_w));
+ *buf++ = opcode;
+ *(sljit_w*)buf = imm;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
+{
+ if (type == SLJIT_JUMP) {
+ *code_ptr++ = 0xe9;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ *code_ptr++ = 0xe8;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = 0x0f;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MW;
+ else
+ *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4);
+ code_ptr += 4;
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->flags_saved = 0;
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
+#else
+ size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+ PUSH_REG(reg_map[TMP_REGISTER]);
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3);
+ }
+#endif
+ if (saveds > 2)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG3]);
+ if (saveds > 1)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG2]);
+ if (saveds > 0)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG1]);
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3];
+ }
+ if (args > 1) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2];
+ }
+ if (args > 2) {
+ *buf++ = 0x8b;
+ *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3);
+ *buf++ = 0x24;
+ *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */
+ }
+#else
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 2;
+ }
+ if (args > 1) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 3;
+ }
+ if (args > 2) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 4;
+ }
+#endif
+
+ local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = local_size;
+ if (temporaries > 3)
+ local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = local_size;
+ if (saveds > 3)
+ local_size += (saveds - 3) * sizeof(sljit_uw);
+
+#ifdef _WIN32
+ if (local_size > 1024) {
+ FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+ }
+#endif
+
+ compiler->local_size = local_size;
+ if (local_size > 0)
+ return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
+ SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = compiler->local_size;
+ if (temporaries > 3)
+ compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = compiler->local_size;
+ if (saveds > 3)
+ compiler->local_size += (saveds - 3) * sizeof(sljit_uw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+ SLJIT_ASSERT(compiler->args >= 0);
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0)
+ FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
+ SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
+
+ size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ size += 2;
+#else
+ if (compiler->args > 0)
+ size += 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+
+ if (compiler->saveds > 0)
+ POP_REG(reg_map[SLJIT_SAVED_REG1]);
+ if (compiler->saveds > 1)
+ POP_REG(reg_map[SLJIT_SAVED_REG2]);
+ if (compiler->saveds > 2)
+ POP_REG(reg_map[SLJIT_SAVED_REG3]);
+ POP_REG(reg_map[TMP_REGISTER]);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ RETN(sizeof(sljit_w));
+ else
+ RET();
+#else
+ if (compiler->args > 0)
+ RETN(compiler->args * sizeof(sljit_w));
+ else
+ RET();
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* Size contains the flags as well. */
+static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
+ /* The register or immediate operand. */
+ int a, sljit_w imma,
+ /* The general operand (not immediate). */
+ int b, sljit_w immb)
+{
+ sljit_ub *buf;
+ sljit_ub *buf_ptr;
+ int flags = size & ~0xf;
+ int inst_size;
+
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+#endif
+
+ size &= 0xf;
+ inst_size = size;
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ inst_size++;
+#endif
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if ((b & 0x0f) == SLJIT_UNUSED)
+ inst_size += sizeof(sljit_w);
+ else if (immb != 0 && !(b & 0xf0)) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_b);
+ else
+ inst_size += sizeof(sljit_w);
+ }
+
+ if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
+ b |= SLJIT_LOCALS_REG << 4;
+
+ if ((b & 0xf0) != SLJIT_UNUSED)
+ inst_size += 1; /* SIB byte. */
+ }
+
+ /* Calculate size of a. */
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= 0x1f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_w);
+ }
+ else
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!buf);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ *buf++ = 0xf2;
+#endif
+ if (flags & EX86_PREF_66)
+ *buf++ = 0x66;
+
+ buf_ptr = buf + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2))
+ *buf_ptr = reg_map[a] << 3;
+ else
+ *buf_ptr = a << 3;
+#else
+ else
+ *buf_ptr = reg_map[a] << 3;
+#endif
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *buf = 0xd1;
+ else
+ *buf = 0xc1;
+ } else
+ *buf = 0xd3;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
+#else
+ *buf_ptr++ |= 0xc0 + reg_map[b];
+#endif
+ else if ((b & 0x0f) != SLJIT_UNUSED) {
+ if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & 0xf0) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_map[b & 0x0f];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3);
+ }
+
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_w);
+ }
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6);
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x05;
+ *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_w);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ *(short*)buf_ptr = imma;
+ else if (!(flags & EX86_SHIFT_INS))
+ *(sljit_w*)buf_ptr = imma;
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
+
+ if (type >= SLJIT_CALL3)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1];
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(type - SLJIT_CALL0);
+ if (type >= SLJIT_CALL3)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
+ if (type >= SLJIT_CALL2)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]);
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = compiler->local_size;
+ if (temporaries > 3)
+ compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = compiler->local_size;
+ if (saveds > 3)
+ compiler->local_size += (saveds - 3) * sizeof(sljit_uw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_map[dst]);
+ return SLJIT_SUCCESS;
+ }
+ else if (dst & SLJIT_MEM) {
+ buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!buf);
+ *buf++ = 0x8f;
+ return SLJIT_SUCCESS;
+ }
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_map[TMP_REGISTER]);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_map[src]);
+ }
+ else if (src & SLJIT_MEM) {
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = 0xff;
+ *buf |= 6 << 3;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ }
+ else {
+ /* SLJIT_IMM. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(5 + 1);
+ *buf++ = 0x68;
+ *(sljit_w*)buf = srcw;
+ buf += sizeof(sljit_w);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_64.c b/src/3rdparty/pcre/sljit/sljitNativeX86_64.c
new file mode 100644
index 0000000000..40d875b841
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_64.c
@@ -0,0 +1,842 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 64-bit arch dependent functions. */
+
+static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));
+ FAIL_IF(!buf);
+ INC_SIZE(2 + sizeof(sljit_w));
+ *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
+ *buf++ = 0xb8 + (reg_map[reg] & 0x7);
+ *(sljit_w*)buf = imm;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
+{
+ if (type < SLJIT_JUMP) {
+ *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
+ *code_ptr++ = 10 + 3;
+ }
+
+ SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
+ *code_ptr++ = REX_W | REX_B;
+ *code_ptr++ = 0xb8 + 1;
+ jump->addr = (sljit_uw)code_ptr;
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MD;
+ else
+ *(sljit_w*)code_ptr = jump->u.target;
+
+ code_ptr += sizeof(sljit_w);
+ *code_ptr++ = REX_B;
+ *code_ptr++ = 0xff;
+ *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
+
+ return code_ptr;
+}
+
+static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
+{
+ sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
+
+ if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
+ *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
+ *(sljit_w*)code_ptr = delta;
+ }
+ else {
+ SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
+ *code_ptr++ = REX_W | REX_B;
+ *code_ptr++ = 0xb8 + 1;
+ *(sljit_w*)code_ptr = addr;
+ code_ptr += sizeof(sljit_w);
+ *code_ptr++ = REX_B;
+ *code_ptr++ = 0xff;
+ *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size, pushed_size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->flags_saved = 0;
+
+ size = saveds;
+ /* Including the return address saved by the call instruction. */
+ pushed_size = (saveds + 1) * sizeof(sljit_w);
+#ifndef _WIN64
+ if (saveds >= 2)
+ size += saveds - 1;
+#else
+ /* Saving the virtual stack pointer. */
+ compiler->has_locals = local_size > 0;
+ if (local_size > 0) {
+ size += 2;
+ pushed_size += sizeof(sljit_w);
+ }
+ if (saveds >= 4)
+ size += saveds - 3;
+ if (temporaries >= 5) {
+ size += (5 - 4) * 2;
+ pushed_size += sizeof(sljit_w);
+ }
+#endif
+ size += args * 3;
+ if (size > 0) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+ if (saveds >= 5) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
+ }
+ if (saveds >= 4) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
+ }
+ if (saveds >= 3) {
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
+ *buf++ = REX_B;
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
+#endif
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]);
+ }
+ if (saveds >= 2) {
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
+ *buf++ = REX_B;
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
+#endif
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]);
+ }
+ if (saveds >= 1) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg);
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
+ }
+#ifdef _WIN64
+ if (temporaries >= 5) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
+ }
+ if (local_size > 0) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_LOCALS_REG] >= 8, locals_reg_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_LOCALS_REG]);
+ }
+#endif
+
+#ifndef _WIN64
+ if (args > 0) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;
+ }
+ if (args > 1) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;
+ }
+ if (args > 2) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;
+ }
+#else
+ if (args > 0) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;
+ }
+ if (args > 1) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;
+ }
+ if (args > 2) {
+ *buf++ = REX_W | REX_B;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;
+ }
+#endif
+ }
+
+ local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
+#ifdef _WIN64
+ local_size += 4 * sizeof(sljit_w);
+ compiler->local_size = local_size;
+ if (local_size > 1024) {
+ /* Allocate the stack for the function itself. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ /* Pushed size must be divisible by 8. */
+ SLJIT_ASSERT(!(pushed_size & 0x7));
+ if (pushed_size & 0x8) {
+ *buf++ = 5 * sizeof(sljit_w);
+ local_size -= 5 * sizeof(sljit_w);
+ } else {
+ *buf++ = 4 * sizeof(sljit_w);
+ local_size -= 4 * sizeof(sljit_w);
+ }
+ FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+ }
+#else
+ compiler->local_size = local_size;
+ if (local_size > 0) {
+#endif
+ /* In case of Win64, local_size is always > 4 * sizeof(sljit_w) */
+ if (local_size <= 127) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ *buf++ = local_size;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!buf);
+ INC_SIZE(7);
+ *buf++ = REX_W;
+ *buf++ = 0x81;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ *(sljit_hw*)buf = local_size;
+ buf += sizeof(sljit_hw);
+ }
+#ifndef _WIN64
+ }
+#endif
+
+#ifdef _WIN64
+ if (compiler->has_locals) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8d;
+ *buf++ = 0x40 | (reg_lmap[SLJIT_LOCALS_REG] << 3) | 0x4;
+ *buf++ = 0x24;
+ *buf = 4 * sizeof(sljit_w);
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int pushed_size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ /* Including the return address saved by the call instruction. */
+ pushed_size = (saveds + 1) * sizeof(sljit_w);
+#ifdef _WIN64
+ compiler->has_locals = local_size > 0;
+ if (local_size > 0)
+ pushed_size += sizeof(sljit_w);
+ if (temporaries >= 5)
+ pushed_size += sizeof(sljit_w);
+#endif
+ compiler->local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
+#ifdef _WIN64
+ compiler->local_size += 4 * sizeof(sljit_w);
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0) {
+ if (compiler->local_size <= 127) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (0 << 3) | 4;
+ *buf = compiler->local_size;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!buf);
+ INC_SIZE(7);
+ *buf++ = REX_W;
+ *buf++ = 0x81;
+ *buf++ = 0xc0 | (0 << 3) | 4;
+ *(sljit_hw*)buf = compiler->local_size;
+ }
+ }
+
+ size = 1 + compiler->saveds;
+#ifndef _WIN64
+ if (compiler->saveds >= 2)
+ size += compiler->saveds - 1;
+#else
+ if (compiler->has_locals)
+ size += 2;
+ if (compiler->saveds >= 4)
+ size += compiler->saveds - 3;
+ if (compiler->temporaries >= 5)
+ size += (5 - 4) * 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+
+#ifdef _WIN64
+ if (compiler->has_locals) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_LOCALS_REG]);
+ }
+ if (compiler->temporaries >= 5) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
+ }
+#endif
+ if (compiler->saveds >= 1)
+ POP_REG(reg_map[SLJIT_SAVED_REG1]);
+ if (compiler->saveds >= 2) {
+#ifndef _WIN64
+ *buf++ = REX_B;
+#endif
+ POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
+ }
+ if (compiler->saveds >= 3) {
+#ifndef _WIN64
+ *buf++ = REX_B;
+#endif
+ POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
+ }
+ if (compiler->saveds >= 4) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
+ }
+ if (compiler->saveds >= 5) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ if (rex != 0) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));
+ FAIL_IF(!buf);
+ INC_SIZE(2 + sizeof(sljit_hw));
+ *buf++ = rex;
+ *buf++ = opcode;
+ *(sljit_hw*)buf = imm;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw));
+ FAIL_IF(!buf);
+ INC_SIZE(1 + sizeof(sljit_hw));
+ *buf++ = opcode;
+ *(sljit_hw*)buf = imm;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
+ /* The register or immediate operand. */
+ int a, sljit_w imma,
+ /* The general operand (not immediate). */
+ int b, sljit_w immb)
+{
+ sljit_ub *buf;
+ sljit_ub *buf_ptr;
+ sljit_ub rex = 0;
+ int flags = size & ~0xf;
+ int inst_size;
+
+ /* The immediate operand must be 32 bit. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+#endif
+
+ size &= 0xf;
+ inst_size = size;
+
+ if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) {
+ if (emit_load_imm64(compiler, TMP_REG3, immb))
+ return NULL;
+ immb = 0;
+ if (b & 0xf)
+ b |= TMP_REG3 << 4;
+ else
+ b |= TMP_REG3;
+ }
+
+ if (!compiler->mode32 && !(flags & EX86_NO_REXW))
+ rex |= REX_W;
+ else if (flags & EX86_REX)
+ rex |= REX;
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ inst_size++;
+#endif
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if ((b & 0x0f) == SLJIT_UNUSED)
+ inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */
+ else {
+ if (reg_map[b & 0x0f] >= 8)
+ rex |= REX_B;
+ if (immb != 0 && !(b & 0xf0)) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_b);
+ else
+ inst_size += sizeof(sljit_hw);
+ }
+ }
+
+#ifndef _WIN64
+ if ((b & 0xf) == SLJIT_LOCALS_REG && (b & 0xf0) == 0)
+ b |= SLJIT_LOCALS_REG << 4;
+#endif
+
+ if ((b & 0xf0) != SLJIT_UNUSED) {
+ inst_size += 1; /* SIB byte. */
+ if (reg_map[(b >> 4) & 0x0f] >= 8)
+ rex |= REX_X;
+ }
+ }
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
+ rex |= REX_B;
+#else
+ else if (reg_map[b] >= 8)
+ rex |= REX_B;
+#endif
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= compiler->mode32 ? 0x1f : 0x3f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_hw);
+ }
+ else {
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+ /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
+ rex |= REX_R;
+#else
+ if (reg_map[a] >= 8)
+ rex |= REX_R;
+#endif
+ }
+
+ if (rex)
+ inst_size++;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!buf);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ *buf++ = 0xf2;
+#endif
+ if (flags & EX86_PREF_66)
+ *buf++ = 0x66;
+ if (rex)
+ *buf++ = rex;
+ buf_ptr = buf + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2))
+ *buf_ptr = reg_lmap[a] << 3;
+ else
+ *buf_ptr = a << 3;
+#else
+ else
+ *buf_ptr = reg_lmap[a] << 3;
+#endif
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *buf = 0xd1;
+ else
+ *buf = 0xc1;
+ } else
+ *buf = 0xd3;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
+#else
+ *buf_ptr++ |= 0xc0 + reg_lmap[b];
+#endif
+ else if ((b & 0x0f) != SLJIT_UNUSED) {
+#ifdef _WIN64
+ SLJIT_ASSERT((b & 0xf0) != (SLJIT_LOCALS_REG << 4));
+#endif
+ if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & 0xf0) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_lmap[b & 0x0f];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3);
+ }
+
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_hw);
+ }
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6);
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = 0x25;
+ *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_hw);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ *(short*)buf_ptr = imma;
+ else if (!(flags & EX86_SHIFT_INS))
+ *(sljit_hw*)buf_ptr = imma;
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!buf);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
+ }
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!buf);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
+ }
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+#ifdef _WIN64
+ compiler->local_size += 4 * sizeof(sljit_w);
+#endif
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REGISTER;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+ if (reg_map[dst] < 8) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_lmap[dst]);
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+
+ INC_SIZE(2);
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[dst]);
+ }
+ }
+ else if (dst & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!buf);
+ *buf++ = 0x8f;
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw));
+ src = TMP_REGISTER;
+ }
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
+ if (reg_map[src] < 8) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_lmap[src]);
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(2 + 1);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[src]);
+ }
+ }
+ else if (src & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = 0xff;
+ *buf |= 6 << 3;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ }
+ else {
+ SLJIT_ASSERT(IS_HALFWORD(srcw));
+ /* SLJIT_IMM. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(5 + 1);
+ *buf++ = 0x68;
+ *(sljit_hw*)buf = srcw;
+ buf += sizeof(sljit_hw);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Extend input */
+/* --------------------------------------------------------------------- */
+
+static int emit_mov_int(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ compiler->mode32 = 0;
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ compiler->mode32 = 1;
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ compiler->mode32 = 0;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))
+ dst_r = src;
+ else {
+ if (sign) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x63;
+ } else {
+ compiler->mode32 = 1;
+ FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
+ compiler->mode32 = 0;
+ }
+ }
+
+ if (dst & SLJIT_MEM) {
+ compiler->mode32 = 1;
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ compiler->mode32 = 0;
+ }
+
+ return SLJIT_SUCCESS;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
new file mode 100644
index 0000000000..0a44163802
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
@@ -0,0 +1,2858 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "x86" SLJIT_CPUINFO;
+}
+
+/*
+ 32b register indexes:
+ 0 - EAX
+ 1 - ECX
+ 2 - EDX
+ 3 - EBX
+ 4 - none
+ 5 - EBP
+ 6 - ESI
+ 7 - EDI
+*/
+
+/*
+ 64b register indexes:
+ 0 - RAX
+ 1 - RCX
+ 2 - RDX
+ 3 - RBX
+ 4 - none
+ 5 - RBP
+ 6 - RSI
+ 7 - RDI
+ 8 - R8 - From now on REX prefix is required
+ 9 - R9
+ 10 - R10
+ 11 - R11
+ 12 - R12
+ 13 - R13
+ 14 - R14
+ 15 - R15
+*/
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+/* Last register + 1. */
+#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
+
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
+ 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
+};
+
+#define CHECK_EXTRA_REGS(p, w, do) \
+ if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
+ w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \
+ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
+ do; \
+ } \
+ else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
+ w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
+ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
+ do; \
+ }
+
+#else /* SLJIT_CONFIG_X86_32 */
+
+/* Last register + 1. */
+#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+
+/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
+ Note: avoid to use r12 and r13 for memory addessing
+ therefore r12 is better for SAVED_EREG than SAVED_REG. */
+#ifndef _WIN64
+/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
+};
+/* low-map. reg_map & 0x7. */
+static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
+};
+#else
+/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 12, 15, 10, 8, 9
+};
+/* low-map. reg_map & 0x7. */
+static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 4, 7, 2, 0, 1
+};
+#endif
+
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+#define REX 0x40
+
+typedef unsigned int sljit_uhw;
+typedef int sljit_hw;
+
+#define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
+#define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
+
+#define CHECK_EXTRA_REGS(p, w, do)
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+#define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
+#endif
+
+/* Size flags for emit_x86_instruction: */
+#define EX86_BIN_INS 0x0010
+#define EX86_SHIFT_INS 0x0020
+#define EX86_REX 0x0040
+#define EX86_NO_REXW 0x0080
+#define EX86_BYTE_ARG 0x0100
+#define EX86_HALF_ARG 0x0200
+#define EX86_PREF_66 0x0400
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+#define EX86_PREF_F2 0x0800
+#define EX86_SSE2 0x1000
+#endif
+
+#define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
+#define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
+
+#define PUSH_REG(r) (*buf++ = (0x50 + (r)))
+#define POP_REG(r) (*buf++ = (0x58 + (r)))
+#define RET() (*buf++ = (0xc3))
+#define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0)
+/* r32, r/m32 */
+#define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
+
+static sljit_ub get_jump_code(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x84;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x85;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x82;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x83;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x87;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x86;
+
+ case SLJIT_C_SIG_LESS:
+ return 0x8c;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0x8d;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0x8f;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0x8e;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ return 0x80;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ return 0x81;
+
+ case SLJIT_C_FLOAT_NAN:
+ return 0x8a;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x8b;
+ }
+ return 0;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type);
+#endif
+
+static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
+{
+ int short_jump;
+ sljit_uw label_addr;
+
+ if (jump->flags & JUMP_LABEL)
+ label_addr = (sljit_uw)(code + jump->u.label->size);
+ else
+ label_addr = jump->u.target;
+ short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll)
+ return generate_far_jump_code(jump, code_ptr, type);
+#endif
+
+ if (type == SLJIT_JUMP) {
+ if (short_jump)
+ *code_ptr++ = 0xeb;
+ else
+ *code_ptr++ = 0xe9;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ short_jump = 0;
+ *code_ptr++ = 0xe8;
+ jump->addr++;
+ }
+ else if (short_jump) {
+ *code_ptr++ = get_jump_code(type) - 0x10;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = 0x0f;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (short_jump) {
+ jump->flags |= PATCH_MB;
+ code_ptr += sizeof(sljit_b);
+ } else {
+ jump->flags |= PATCH_MW;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code_ptr += sizeof(sljit_w);
+#else
+ code_ptr += sizeof(sljit_hw);
+#endif
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ub *code;
+ sljit_ub *code_ptr;
+ sljit_ub *buf_ptr;
+ sljit_ub *buf_end;
+ sljit_ub len;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+ code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = buf->memory;
+ buf_end = buf_ptr + buf->used_size;
+ do {
+ len = *buf_ptr++;
+ if (len > 0) {
+ /* The code is already generated. */
+ SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
+ code_ptr += len;
+ buf_ptr += len;
+ }
+ else {
+ if (*buf_ptr >= 4) {
+ jump->addr = (sljit_uw)code_ptr;
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
+ else
+ code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
+ jump = jump->next;
+ }
+ else if (*buf_ptr == 0) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ else if (*buf_ptr == 1) {
+ const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
+ const_ = const_->next;
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
+ buf_ptr++;
+ *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w));
+ code_ptr += sizeof(sljit_w);
+ buf_ptr += sizeof(sljit_w) - 1;
+#else
+ code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
+ buf_ptr += sizeof(sljit_w);
+#endif
+ }
+ buf_ptr++;
+ }
+ } while (buf_ptr < buf_end);
+ SLJIT_ASSERT(buf_ptr == buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+ jump = compiler->jumps;
+ while (jump) {
+ if (jump->flags & PATCH_MB) {
+ SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);
+ *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
+ } else if (jump->flags & PATCH_MW) {
+ if (jump->flags & JUMP_LABEL) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
+#else
+ SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
+ *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
+#else
+ SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
+ *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
+#endif
+ }
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ else if (jump->flags & PATCH_MD)
+ *(sljit_w*)jump->addr = jump->u.label->addr;
+#endif
+
+ jump = jump->next;
+ }
+
+ /* Maybe we waste some space because of short jumps. */
+ SLJIT_ASSERT(code_ptr <= code + compiler->size);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size;
+ return (void*)code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static int emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+static int emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+static int emit_mov(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw);
+
+static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+ *buf++ = 0x9c; /* pushfd */
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!buf);
+ INC_SIZE(6);
+ *buf++ = 0x9c; /* pushfq */
+ *buf++ = 0x48;
+#endif
+ *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
+ *buf++ = 0x64;
+ *buf++ = 0x24;
+ *buf++ = sizeof(sljit_w);
+ compiler->flags_saved = 1;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!buf);
+ INC_SIZE(6);
+ *buf++ = 0x48;
+#endif
+ *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
+ *buf++ = 0x64;
+ *buf++ = 0x24;
+ *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
+ *buf++ = 0x9d; /* popfd / popfq */
+ compiler->flags_saved = keep_flags;
+ return SLJIT_SUCCESS;
+}
+
+#ifdef _WIN32
+#include <malloc.h>
+
+static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
+{
+ /* Workaround for calling _chkstk. */
+ alloca(local_size);
+}
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#include "sljitNativeX86_32.c"
+#else
+#include "sljitNativeX86_64.c"
+#endif
+
+static int emit_mov(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ /* No destination, doesn't need to setup flags. */
+ if (src & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ }
+ return SLJIT_SUCCESS;
+ }
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
+ code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+ }
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ if (!compiler->mode32) {
+ if (NOT_HALFWORD(srcw))
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ else
+ return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+ }
+#endif
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ return SLJIT_SUCCESS;
+ }
+
+ /* Memory to memory move. Requires two instruction. */
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+}
+
+#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ sljit_ub *buf;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int size;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_BREAKPOINT:
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0xcc;
+ break;
+ case SLJIT_NOP:
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x90;
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ compiler->flags_saved = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+#ifdef _WIN64
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_TEMPORARY_REG1] == 0
+ && reg_map[SLJIT_TEMPORARY_REG2] == 2
+ && reg_map[TMP_REGISTER] > 7,
+ invalid_register_assignment_for_div_mul);
+#else
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_TEMPORARY_REG1] == 0
+ && reg_map[SLJIT_TEMPORARY_REG2] < 7
+ && reg_map[TMP_REGISTER] == 2,
+ invalid_register_assignment_for_div_mul);
+#endif
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+
+ op = GET_OPCODE(op);
+ if (op == SLJIT_UDIV) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
+ buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
+#else
+ buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+#endif
+ FAIL_IF(!buf);
+ *buf = 0x33;
+ }
+
+ if (op == SLJIT_SDIV) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
+#endif
+
+ /* CDQ instruction */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x99;
+#else
+ if (compiler->mode32) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x99;
+ } else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = REX_W;
+ *buf = 0x99;
+ }
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = 0xf7;
+ *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
+#else
+#ifdef _WIN64
+ size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
+#else
+ size = (!compiler->mode32) ? 3 : 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+ INC_SIZE(size);
+#ifdef _WIN64
+ if (!compiler->mode32)
+ *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
+ else if (op >= SLJIT_UDIV)
+ *buf++ = REX_B;
+ *buf++ = 0xf7;
+ *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
+#else
+ if (!compiler->mode32)
+ *buf++ = REX_W;
+ *buf++ = 0xf7;
+ *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
+#endif
+#endif
+ switch (op) {
+ case SLJIT_UMUL:
+ *buf |= 4 << 3;
+ break;
+ case SLJIT_SMUL:
+ *buf |= 5 << 3;
+ break;
+ case SLJIT_UDIV:
+ *buf |= 6 << 3;
+ break;
+ case SLJIT_SDIV:
+ *buf |= 7 << 3;
+ break;
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
+#endif
+ break;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define ENCODE_PREFIX(prefix) \
+ do { \
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
+ FAIL_IF(!code); \
+ INC_CSIZE(1); \
+ *code = (prefix); \
+ } while (0)
+
+static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int work_r;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ return emit_load_imm64(compiler, dst, srcw);
+#endif
+ }
+ code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc6;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg_map[src] >= 4) {
+ SLJIT_ASSERT(dst_r == TMP_REGISTER);
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ } else
+ dst_r = src;
+#else
+ dst_r = src;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) {
+ /* src, dst are registers. */
+ SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER);
+ if (reg_map[dst] < 4) {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbe : 0xb6;
+ }
+ else {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ if (sign) {
+ /* shl reg, 24 */
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!code);
+ *code |= 0x4 << 3;
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!code);
+ /* shr/sar reg, 24 */
+ *code |= 0x7 << 3;
+ }
+ else {
+ /* and dst, 0xff */
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
+ FAIL_IF(!code);
+ *(code + 1) |= 0x4 << 3;
+ }
+ }
+ return SLJIT_SUCCESS;
+ }
+#endif
+ else {
+ /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbe : 0xb6;
+ }
+
+ if (dst & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst_r == TMP_REGISTER) {
+ /* Find a non-used register, whose reg_map[src] < 4. */
+ if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) {
+ if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4))
+ work_r = SLJIT_TEMPORARY_REG3;
+ else
+ work_r = SLJIT_TEMPORARY_REG2;
+ }
+ else {
+ if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
+ work_r = SLJIT_TEMPORARY_REG1;
+ else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2)
+ work_r = SLJIT_TEMPORARY_REG3;
+ else
+ work_r = SLJIT_TEMPORARY_REG2;
+ }
+
+ if (work_r == SLJIT_TEMPORARY_REG1) {
+ ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+
+ if (work_r == SLJIT_TEMPORARY_REG1) {
+ ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_mov_half(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ return emit_load_imm64(compiler, dst, srcw);
+#endif
+ }
+ code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
+ dst_r = src;
+ else {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbf : 0xb7;
+ }
+
+ if (dst & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_unary(struct sljit_compiler *compiler, int un_index,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == src && dstw == srcw) {
+ /* Same input and output */
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+}
+
+static int emit_not_with_flags(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+}
+
+static int emit_clz(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ SLJIT_UNUSED_ARG(op);
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ /* Just set the zero flag. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0);
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
+#endif
+ FAIL_IF(!code);
+ *code |= 0x5 << 3;
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ srcw = 0;
+ }
+
+ code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xbd;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
+ dst_r = dst;
+ else {
+ /* Find an unused temporary register. */
+ if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
+ dst_r = SLJIT_TEMPORARY_REG1;
+ else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4))
+ dst_r = SLJIT_TEMPORARY_REG2;
+ else
+ dst_r = SLJIT_TEMPORARY_REG3;
+ EMIT_MOV(compiler, dst, dstw, dst_r, 0);
+ }
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
+#else
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2;
+ compiler->mode32 = 0;
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31);
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0x45;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
+#endif
+ FAIL_IF(!code);
+ *(code + 1) |= 0x6 << 3;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+#else
+ if (dst & SLJIT_MEM)
+ EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int update = 0;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int dst_is_ereg = 0;
+ int src_is_ereg = 0;
+#else
+ #define src_is_ereg 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+ CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
+ CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
+
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
+ op = GET_OPCODE(op);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
+ if (op >= SLJIT_MOVU) {
+ update = 1;
+ op -= 7;
+ }
+
+ if (src & SLJIT_IMM) {
+ switch (op) {
+ case SLJIT_MOV_UB:
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOV_SB:
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOV_UH:
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOV_SH:
+ srcw = (signed short)srcw;
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_UI:
+ srcw = (unsigned int)srcw;
+ break;
+ case SLJIT_MOV_SI:
+ srcw = (signed int)srcw;
+ break;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg))
+ return emit_mov(compiler, dst, dstw, src, srcw);
+#endif
+ }
+
+ if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) {
+ code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ src &= SLJIT_MEM | 0xf;
+ srcw = 0;
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) {
+ SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
+ dst = TMP_REGISTER;
+ }
+#endif
+
+ switch (op) {
+ case SLJIT_MOV:
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+#endif
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_UB:
+ FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
+ break;
+ case SLJIT_MOV_SB:
+ FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
+ break;
+ case SLJIT_MOV_UH:
+ FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
+ break;
+ case SLJIT_MOV_SH:
+ FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_UI:
+ FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
+ break;
+ case SLJIT_MOV_SI:
+ FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
+ break;
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER)
+ return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0);
+#endif
+
+ if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) {
+ code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_NOT:
+ if (SLJIT_UNLIKELY(op & SLJIT_SET_E))
+ return emit_not_with_flags(compiler, dst, dstw, src, srcw);
+ return emit_unary(compiler, 0x2, dst, dstw, src, srcw);
+
+ case SLJIT_NEG:
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_unary(compiler, 0x3, dst, dstw, src, srcw);
+
+ case SLJIT_CLZ:
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_clz(compiler, op, dst, dstw, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #undef src_is_ereg
+#endif
+}
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
+ if (IS_HALFWORD(immw) || compiler->mode32) { \
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!code); \
+ *(code + 1) |= (_op_imm_); \
+ } \
+ else { \
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
+ FAIL_IF(!code); \
+ *code = (_op_mr_); \
+ }
+
+#define BINARY_EAX_IMM(_op_eax_imm_, immw) \
+ FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw))
+
+#else
+
+#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!code); \
+ *(code + 1) |= (_op_imm_);
+
+#define BINARY_EAX_IMM(_op_eax_imm_, immw) \
+ FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
+
+#endif
+
+static int emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) {
+ /* Special exception for sljit_emit_cond_value. */
+ code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* Only for cumulative operations. */
+ if (dst == src2 && dstw == src2w) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src1w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_mul(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ /* Register destination. */
+ if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+ else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src2 & SLJIT_IMM) {
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
+ src2 = dst_r;
+ src2w = 0;
+ }
+
+ if (src1w <= 127 && src1w >= -128) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x6b;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!code);
+ INC_CSIZE(1);
+ *code = (sljit_b)src1w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_w*)code = src1w;
+ }
+#else
+ else if (IS_HALFWORD(src1w)) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_hw*)code = (sljit_hw)src1w;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
+ if (dst_r != src2)
+ EMIT_MOV(compiler, dst_r, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+#endif
+ }
+ else if (src2 & SLJIT_IMM) {
+ /* Note: src1 is NOT immediate. */
+
+ if (src2w <= 127 && src2w >= -128) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x6b;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!code);
+ INC_CSIZE(1);
+ *code = (sljit_b)src2w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_w*)code = src2w;
+ }
+#else
+ else if (IS_HALFWORD(src2w)) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_hw*)code = (sljit_hw)src2w;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
+ if (dst_r != src1)
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+#endif
+ }
+ else {
+ /* Neither argument is immediate. */
+ if (ADDRESSING_DEPENDS_ON(src2, dst_r))
+ dst_r = TMP_REGISTER;
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+
+ if (dst_r == TMP_REGISTER)
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_lea_binary(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+ int dst_r, done = 0;
+
+ /* These cases better be left to handled by normal way. */
+ if (dst == src1 && dstw == src1w)
+ return SLJIT_ERR_UNSUPPORTED;
+ if (dst == src2 && dstw == src2w)
+ return SLJIT_ERR_UNSUPPORTED;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ /* It is not possible to be both SLJIT_LOCALS_REG. */
+ if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w);
+#else
+ if (src2 & SLJIT_IMM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
+#endif
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w);
+#else
+ if (src1 & SLJIT_IMM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
+#endif
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+
+ if (done) {
+ if (dst_r == TMP_REGISTER)
+ return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+static int emit_cmp_binary(struct sljit_compiler *compiler,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(0x3d, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x3b;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x39;
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 & SLJIT_IMM) {
+ if (src1 & SLJIT_IMM) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ src1 = TMP_REGISTER;
+ src1w = 0;
+ }
+ BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x3b;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static int emit_test_binary(struct sljit_compiler *compiler,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(0xa9, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(0xa9, src1w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src1w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static int emit_shift(struct sljit_compiler *compiler,
+ sljit_ub mode,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
+ if (dst == src1 && dstw == src1w) {
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
+ if (src1 != dst)
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ }
+ else {
+ /* This case is really difficult, since ecx itself may used for
+ addressing, and we must ensure to work even in that case. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
+#else
+ /* [esp - 4] is reserved for eflags. */
+ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
+#endif
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
+#else
+ /* [esp - 4] is reserved for eflags. */
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)));
+#endif
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_shift_with_flags(struct sljit_compiler *compiler,
+ sljit_ub mode, int set_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* The CPU does not set flags if the shift count is 0. */
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#else
+ if ((src2w & 0x1f) != 0)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#endif
+ if (!set_flags)
+ return emit_mov(compiler, dst, dstw, src1, src1w);
+ /* OR dst, src, 0 */
+ return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
+ dst, dstw, src1, src1w, SLJIT_IMM, 0);
+ }
+
+ if (!set_flags)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+
+ if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
+ FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
+
+ FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ CHECK_EXTRA_REGS(src1, src1w, (void)0);
+ CHECK_EXTRA_REGS(src2, src2w, (void)0);
+
+ if (GET_OPCODE(op) >= SLJIT_MUL) {
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op)) {
+ if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ADDC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op)) {
+ if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ if (dst == SLJIT_UNUSED)
+ return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
+ return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUBC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_MUL:
+ return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_AND:
+ if (dst == SLJIT_UNUSED)
+ return emit_test_binary(compiler, src1, src1w, src2, src2w);
+ return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_OR:
+ return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_XOR:
+ return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SHL:
+ return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_LSHR:
+ return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ASHR:
+ return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
+ || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
+ return -1;
+#endif
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size > 0 && size < 16);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+ INC_SIZE(size);
+ SLJIT_MEMMOVE(buf, instruction, size);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+static int sse2_available = 0;
+#endif
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+
+/* Alignment + 2 * 16 bytes. */
+static sljit_i sse2_data[3 + 4 + 4];
+static sljit_i *sse2_buffer;
+
+static void init_compiler()
+{
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+ int features = 0;
+#endif
+
+ sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
+ sse2_buffer[0] = 0;
+ sse2_buffer[1] = 0x80000000;
+ sse2_buffer[4] = 0xffffffff;
+ sse2_buffer[5] = 0x7fffffff;
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+#ifdef __GNUC__
+ /* AT&T syntax. */
+ asm (
+ "pushl %%ebx\n"
+ "movl $0x1, %%eax\n"
+ "cpuid\n"
+ "popl %%ebx\n"
+ "movl %%edx, %0\n"
+ : "=g" (features)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+ /* Intel syntax. */
+ __asm {
+ mov eax, 1
+ push ebx
+ cpuid
+ pop ebx
+ mov features, edx
+ }
+#else
+ #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
+#endif
+ sse2_available = (features >> 26) & 0x1;
+#endif
+}
+
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+
+static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
+ int xmm1, int xmm2, sljit_w xmm2w)
+{
+ sljit_ub *buf;
+
+ buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!buf);
+ *buf++ = 0x0f;
+ *buf = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
+ int xmm1, int xmm2, sljit_w xmm2w)
+{
+ sljit_ub *buf;
+
+ buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!buf);
+ *buf++ = 0x0f;
+ *buf = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
+ int dst, int src, sljit_w srcw)
+{
+ return emit_sse2(compiler, 0x10, dst, src, srcw);
+}
+
+static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw, int src)
+{
+ return emit_sse2(compiler, 0x11, src, dst, dstw);
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ compiler->flags_saved = 0;
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
+ dst_r = dst;
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
+ }
+ return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
+ }
+
+ if (op == SLJIT_FMOV) {
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
+ return emit_sse2_load(compiler, dst, src, srcw);
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
+ return emit_sse2_store(compiler, dst, dstw, src);
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ }
+
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
+ dst_r = dst;
+ if (dst != src)
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
+ }
+
+ switch (op) {
+ case SLJIT_FNEG:
+ FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
+ break;
+
+ case SLJIT_FABS:
+ FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
+ dst_r = dst;
+ if (dst == src1)
+ ; /* Do nothing here. */
+ else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
+ /* Swap arguments. */
+ src2 = src1;
+ src2w = src1w;
+ }
+ else if (dst != src2)
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
+ }
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
+
+static int emit_fld(struct sljit_compiler *compiler,
+ int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = 0xd9;
+ *buf = 0xc0 + src - 1;
+ return SLJIT_SUCCESS;
+ }
+
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf = 0xdd;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_fop(struct sljit_compiler *compiler,
+ sljit_ub st_arg, sljit_ub st_arg2,
+ sljit_ub m64fp_arg, sljit_ub m64fp_arg2,
+ int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = st_arg;
+ *buf = st_arg2 + src;
+ return SLJIT_SUCCESS;
+ }
+
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = m64fp_arg;
+ *buf |= m64fp_arg2;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_fop_regs(struct sljit_compiler *compiler,
+ sljit_ub st_arg, sljit_ub st_arg2,
+ int src)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = st_arg;
+ *buf = st_arg2 + src;
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_ub *buf;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ compiler->flags_saved = 0;
+#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ FAIL_IF(emit_fld(compiler, dst, dstw));
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw));
+
+ /* Copy flags. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3);
+ *buf++ = 0xdf;
+ *buf++ = 0xe0;
+ /* Note: lahf is not supported on all x86-64 architectures. */
+ *buf++ = 0x9e;
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
+#else
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fld(compiler, dst, dstw));
+ FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
+ } else {
+ FAIL_IF(emit_fld(compiler, src, srcw));
+ FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw));
+ FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
+ FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0));
+ }
+#endif
+ return SLJIT_SUCCESS;
+ }
+
+ FAIL_IF(emit_fld(compiler, src, srcw));
+
+ switch (op) {
+ case SLJIT_FNEG:
+ FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
+ break;
+ }
+
+ FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
+ FAIL_IF(emit_fld(compiler, src2, src2w));
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
+ break;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ FAIL_IF(emit_fld(compiler, src1, src1w));
+
+ if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
+ break;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
+ break;
+ }
+
+ FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ if (sse2_available)
+ return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
+ else
+ return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ if (sse2_available)
+ return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+ else
+ return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ sljit_ub *buf;
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ /* We should restore the flags before the label,
+ since other taken jumps has their own flags as well. */
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!buf);
+
+ *buf++ = 0;
+ *buf++ = 0;
+
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if ((type & 0xff) <= SLJIT_JUMP)
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type >= SLJIT_CALL1)
+ PTR_FAIL_IF(call_with_args(compiler, type));
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
+#else
+ compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
+#endif
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF_NULL(buf);
+
+ *buf++ = 0;
+ *buf++ = type + 4;
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ sljit_ub *code;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if (type <= SLJIT_JUMP)
+ FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ if (type >= SLJIT_CALL1) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (src == SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ src = TMP_REGISTER;
+ }
+ if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
+ if (src & 0xf0) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ }
+ else
+ srcw += sizeof(sljit_w);
+ }
+#else
+ if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
+ if (src & 0xf0) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ }
+ else
+ srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
+ }
+#endif
+#endif
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
+ if (src == SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ src = TMP_REGISTER;
+ }
+#endif
+ FAIL_IF(call_with_args(compiler, type));
+ }
+
+ if (src == SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->u.target = srcw;
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += 5;
+#else
+ compiler->size += 10 + 3;
+#endif
+
+ code = (sljit_ub*)ensure_buf(compiler, 2);
+ FAIL_IF_NULL(code);
+
+ *code++ = 0;
+ *code++ = type + 4;
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0xff;
+ *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ sljit_ub *buf;
+ sljit_ub cond_set = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int reg;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ FAIL_IF(emit_restore_flags(compiler, 0));
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ cond_set = 0x94;
+ break;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ cond_set = 0x95;
+ break;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ cond_set = 0x92;
+ break;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ cond_set = 0x93;
+ break;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ cond_set = 0x97;
+ break;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ cond_set = 0x96;
+ break;
+
+ case SLJIT_C_SIG_LESS:
+ cond_set = 0x9c;
+ break;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ cond_set = 0x9d;
+ break;
+
+ case SLJIT_C_SIG_GREATER:
+ cond_set = 0x9f;
+ break;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ cond_set = 0x9e;
+ break;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ cond_set = 0x90;
+ break;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ cond_set = 0x91;
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ cond_set = 0x9a;
+ break;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ cond_set = 0x9b;
+ break;
+ }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4 + 4);
+ /* Set low register to conditional flag. */
+ *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_lmap[reg];
+ *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
+
+ if (reg == TMP_REGISTER) {
+ if (op == SLJIT_MOV) {
+ compiler->mode32 = 0;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+ else {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
+ }
+ }
+#else
+ if (op == SLJIT_MOV) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3);
+ /* Set low byte to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_map[dst];
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3);
+ /* Set al to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
+ *buf = 0xC0 | (reg_map[dst] << 3);
+ else {
+ *buf = 0xC0;
+ EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
+ }
+
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
+ }
+ }
+ else {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3);
+
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_map[dst];
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3 + 1);
+ /* Set al to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x90 + reg_map[TMP_REGISTER];
+ }
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ sljit_ub *buf;
+ struct sljit_const *const_;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int reg;
+#endif
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ if (emit_load_imm64(compiler, reg, init_value))
+ return NULL;
+#else
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REGISTER;
+
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
+ return NULL;
+#endif
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!buf);
+
+ *buf++ = 0;
+ *buf++ = 1;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
+ if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
+ return NULL;
+#endif
+
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)addr = new_addr - (addr + 4);
+#else
+ *(sljit_uw*)addr = new_addr;
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ *(sljit_w*)addr = new_constant;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitUtils.c b/src/3rdparty/pcre/sljit/sljitUtils.c
new file mode 100644
index 0000000000..98beaa0b5e
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitUtils.c
@@ -0,0 +1,244 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ------------------------------------------------------------------------ */
+/* Locks */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+#ifdef _WIN32
+
+#include "windows.h"
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static HANDLE allocator_mutex = 0;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!allocator_mutex)
+ allocator_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(allocator_mutex, INFINITE);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ ReleaseMutex(allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+static HANDLE global_mutex = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!global_mutex)
+ global_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(global_mutex, INFINITE);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ ReleaseMutex(global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#else /* _WIN32 */
+
+#include "pthread.h"
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ pthread_mutex_lock(&allocator_mutex);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ pthread_mutex_unlock(&allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ pthread_mutex_lock(&global_mutex);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ pthread_mutex_unlock(&global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#endif /* _WIN32 */
+
+/* ------------------------------------------------------------------------ */
+/* Stack */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+#ifdef _WIN32
+#include "windows.h"
+#else
+#include <sys/mman.h>
+#include <unistd.h>
+#endif
+
+/* Planning to make it even more clever in the future. */
+static sljit_w sljit_page_align = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
+{
+ struct sljit_stack *stack;
+ union {
+ void *ptr;
+ sljit_uw uw;
+ } base;
+#ifdef _WIN32
+ SYSTEM_INFO si;
+#endif
+
+ if (limit > max_limit || limit < 1)
+ return NULL;
+
+#ifdef _WIN32
+ if (!sljit_page_align) {
+ GetSystemInfo(&si);
+ sljit_page_align = si.dwPageSize - 1;
+ }
+#else
+ if (!sljit_page_align) {
+ sljit_page_align = sysconf(_SC_PAGESIZE);
+ /* Should never happen. */
+ if (sljit_page_align < 0)
+ sljit_page_align = 4096;
+ sljit_page_align--;
+ }
+#endif
+
+ /* Align limit and max_limit. */
+ max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
+
+ stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
+ if (!stack)
+ return NULL;
+
+#ifdef _WIN32
+ base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
+ if (!base.ptr) {
+ SLJIT_FREE(stack);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base;
+ stack->max_limit = stack->base + max_limit;
+ if (sljit_stack_resize(stack, stack->base + limit)) {
+ sljit_free_stack(stack);
+ return NULL;
+ }
+#else
+ base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (base.ptr == MAP_FAILED) {
+ SLJIT_FREE(stack);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base + limit;
+ stack->max_limit = stack->base + max_limit;
+#endif
+ stack->top = stack->base;
+ return stack;
+}
+
+#undef PAGE_ALIGN
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
+{
+#ifdef _WIN32
+ VirtualFree((void*)stack->base, 0, MEM_RELEASE);
+#else
+ munmap((void*)stack->base, stack->max_limit - stack->base);
+#endif
+ SLJIT_FREE(stack);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
+{
+ sljit_uw aligned_old_limit;
+ sljit_uw aligned_new_limit;
+
+ if ((new_limit > stack->max_limit) || (new_limit < stack->base))
+ return -1;
+#ifdef _WIN32
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ if (aligned_new_limit != aligned_old_limit) {
+ if (aligned_new_limit > aligned_old_limit) {
+ if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
+ return -1;
+ }
+ else {
+ if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
+ return -1;
+ }
+ }
+ stack->limit = new_limit;
+ return 0;
+#else
+ if (new_limit >= stack->limit) {
+ stack->limit = new_limit;
+ return 0;
+ }
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ if (aligned_new_limit < aligned_old_limit)
+ madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
+ stack->limit = new_limit;
+ return 0;
+#endif
+}
+
+#endif /* SLJIT_UTIL_STACK */
+
+#endif
diff --git a/src/3rdparty/pcre/ucp.h b/src/3rdparty/pcre/ucp.h
new file mode 100644
index 0000000000..34077fe07e
--- /dev/null
+++ b/src/3rdparty/pcre/ucp.h
@@ -0,0 +1,165 @@
+/*************************************************
+* Unicode Property Table handler *
+*************************************************/
+
+#ifndef _UCP_H
+#define _UCP_H
+
+/* This file contains definitions of the property values that are returned by
+the UCD access macros. New values that are added for new releases of Unicode
+should always be at the end of each enum, for backwards compatibility. */
+
+/* These are the general character categories. */
+
+enum {
+ ucp_C, /* Other */
+ ucp_L, /* Letter */
+ ucp_M, /* Mark */
+ ucp_N, /* Number */
+ ucp_P, /* Punctuation */
+ ucp_S, /* Symbol */
+ ucp_Z /* Separator */
+};
+
+/* These are the particular character types. */
+
+enum {
+ ucp_Cc, /* Control */
+ ucp_Cf, /* Format */
+ ucp_Cn, /* Unassigned */
+ ucp_Co, /* Private use */
+ ucp_Cs, /* Surrogate */
+ ucp_Ll, /* Lower case letter */
+ ucp_Lm, /* Modifier letter */
+ ucp_Lo, /* Other letter */
+ ucp_Lt, /* Title case letter */
+ ucp_Lu, /* Upper case letter */
+ ucp_Mc, /* Spacing mark */
+ ucp_Me, /* Enclosing mark */
+ ucp_Mn, /* Non-spacing mark */
+ ucp_Nd, /* Decimal number */
+ ucp_Nl, /* Letter number */
+ ucp_No, /* Other number */
+ ucp_Pc, /* Connector punctuation */
+ ucp_Pd, /* Dash punctuation */
+ ucp_Pe, /* Close punctuation */
+ ucp_Pf, /* Final punctuation */
+ ucp_Pi, /* Initial punctuation */
+ ucp_Po, /* Other punctuation */
+ ucp_Ps, /* Open punctuation */
+ ucp_Sc, /* Currency symbol */
+ ucp_Sk, /* Modifier symbol */
+ ucp_Sm, /* Mathematical symbol */
+ ucp_So, /* Other symbol */
+ ucp_Zl, /* Line separator */
+ ucp_Zp, /* Paragraph separator */
+ ucp_Zs /* Space separator */
+};
+
+/* These are the script identifications. */
+
+enum {
+ ucp_Arabic,
+ ucp_Armenian,
+ ucp_Bengali,
+ ucp_Bopomofo,
+ ucp_Braille,
+ ucp_Buginese,
+ ucp_Buhid,
+ ucp_Canadian_Aboriginal,
+ ucp_Cherokee,
+ ucp_Common,
+ ucp_Coptic,
+ ucp_Cypriot,
+ ucp_Cyrillic,
+ ucp_Deseret,
+ ucp_Devanagari,
+ ucp_Ethiopic,
+ ucp_Georgian,
+ ucp_Glagolitic,
+ ucp_Gothic,
+ ucp_Greek,
+ ucp_Gujarati,
+ ucp_Gurmukhi,
+ ucp_Han,
+ ucp_Hangul,
+ ucp_Hanunoo,
+ ucp_Hebrew,
+ ucp_Hiragana,
+ ucp_Inherited,
+ ucp_Kannada,
+ ucp_Katakana,
+ ucp_Kharoshthi,
+ ucp_Khmer,
+ ucp_Lao,
+ ucp_Latin,
+ ucp_Limbu,
+ ucp_Linear_B,
+ ucp_Malayalam,
+ ucp_Mongolian,
+ ucp_Myanmar,
+ ucp_New_Tai_Lue,
+ ucp_Ogham,
+ ucp_Old_Italic,
+ ucp_Old_Persian,
+ ucp_Oriya,
+ ucp_Osmanya,
+ ucp_Runic,
+ ucp_Shavian,
+ ucp_Sinhala,
+ ucp_Syloti_Nagri,
+ ucp_Syriac,
+ ucp_Tagalog,
+ ucp_Tagbanwa,
+ ucp_Tai_Le,
+ ucp_Tamil,
+ ucp_Telugu,
+ ucp_Thaana,
+ ucp_Thai,
+ ucp_Tibetan,
+ ucp_Tifinagh,
+ ucp_Ugaritic,
+ ucp_Yi,
+ /* New for Unicode 5.0: */
+ ucp_Balinese,
+ ucp_Cuneiform,
+ ucp_Nko,
+ ucp_Phags_Pa,
+ ucp_Phoenician,
+ /* New for Unicode 5.1: */
+ ucp_Carian,
+ ucp_Cham,
+ ucp_Kayah_Li,
+ ucp_Lepcha,
+ ucp_Lycian,
+ ucp_Lydian,
+ ucp_Ol_Chiki,
+ ucp_Rejang,
+ ucp_Saurashtra,
+ ucp_Sundanese,
+ ucp_Vai,
+ /* New for Unicode 5.2: */
+ ucp_Avestan,
+ ucp_Bamum,
+ ucp_Egyptian_Hieroglyphs,
+ ucp_Imperial_Aramaic,
+ ucp_Inscriptional_Pahlavi,
+ ucp_Inscriptional_Parthian,
+ ucp_Javanese,
+ ucp_Kaithi,
+ ucp_Lisu,
+ ucp_Meetei_Mayek,
+ ucp_Old_South_Arabian,
+ ucp_Old_Turkic,
+ ucp_Samaritan,
+ ucp_Tai_Tham,
+ ucp_Tai_Viet,
+ /* New for Unicode 6.0.0: */
+ ucp_Batak,
+ ucp_Brahmi,
+ ucp_Mandaic
+};
+
+#endif
+
+/* End of ucp.h */
diff --git a/src/concurrent/qtconcurrentexception.cpp b/src/concurrent/qtconcurrentexception.cpp
index caeaa8d9be..57eb604d39 100644
--- a/src/concurrent/qtconcurrentexception.cpp
+++ b/src/concurrent/qtconcurrentexception.cpp
@@ -69,10 +69,10 @@ QT_BEGIN_NAMESPACE
When using QFuture, transferred exceptions will be thrown when calling the following functions:
\list
- \o QFuture::waitForFinished()
- \o QFuture::result()
- \o QFuture::resultAt()
- \o QFuture::results()
+ \li QFuture::waitForFinished()
+ \li QFuture::result()
+ \li QFuture::resultAt()
+ \li QFuture::results()
\endlist
*/
diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp
index e51626ed13..656ecf7370 100644
--- a/src/concurrent/qtconcurrentrun.cpp
+++ b/src/concurrent/qtconcurrentrun.cpp
@@ -121,9 +121,9 @@
this:
\list
- \o To call a function that takes more than 5 arguments.
- \o To simplify calling a function with constant arguments.
- \o Changing the order of arguments.
+ \li To call a function that takes more than 5 arguments.
+ \li To simplify calling a function with constant arguments.
+ \li Changing the order of arguments.
\endlist
See the documentation for the relevant functions for details on how to use
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index 67598f4f70..5acc13c6f3 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -30,6 +30,9 @@ list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE)
set(QT_LIBINFIX \"$${QT_LIBINFIX}\")
!!ENDIF
+set(QT_CONFIG \"$${CONFIG}\")
+set(QT_QCONFIG \"$${QT_CONFIG}\")
+
!!IF !isEmpty(CMAKE_WINDOWS_BUILD)
set(Qt5Core_QTMAIN_LIBRARIES Qt5::WinMain)
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 35a340836d..2262a3836e 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -98,18 +98,18 @@ QT_BEGIN_NAMESPACE
supported QVariant types:
\list
- \o \l{QMetaType::}{Int}
- \o \l{QMetaType::}{Double}
- \o \l{QMetaType::}{Float}
- \o \l{QMetaType::}{QLine}
- \o \l{QMetaType::}{QLineF}
- \o \l{QMetaType::}{QPoint}
- \o \l{QMetaType::}{QPointF}
- \o \l{QMetaType::}{QSize}
- \o \l{QMetaType::}{QSizeF}
- \o \l{QMetaType::}{QRect}
- \o \l{QMetaType::}{QRectF}
- \o \l{QMetaType::}{QColor}
+ \li \l{QMetaType::}{Int}
+ \li \l{QMetaType::}{Double}
+ \li \l{QMetaType::}{Float}
+ \li \l{QMetaType::}{QLine}
+ \li \l{QMetaType::}{QLineF}
+ \li \l{QMetaType::}{QPoint}
+ \li \l{QMetaType::}{QPointF}
+ \li \l{QMetaType::}{QSize}
+ \li \l{QMetaType::}{QSizeF}
+ \li \l{QMetaType::}{QRect}
+ \li \l{QMetaType::}{QRectF}
+ \li \l{QMetaType::}{QColor}
\endlist
If you need to interpolate other variant types, including custom
diff --git a/src/corelib/codecs/codecs.qdoc b/src/corelib/codecs/codecs.qdoc
index 2127a0a4cf..669072f789 100644
--- a/src/corelib/codecs/codecs.qdoc
+++ b/src/corelib/codecs/codecs.qdoc
@@ -77,9 +77,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -126,9 +126,9 @@
Currently, the Big5-HKSCS tables are generated from the following
sources, and with the Euro character added:
\list 1
- \o \l{http://www.microsoft.com/typography/unicode/950.txt}
- \o \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5-iso.txt}
- \o \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5cmp.txt}
+ \li \l{http://www.microsoft.com/typography/unicode/950.txt}
+ \li \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5-iso.txt}
+ \li \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5cmp.txt}
\endlist
There may be more fine-tuning to the QBig5hkscsCodec to maximize its
@@ -147,9 +147,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -195,9 +195,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -238,9 +238,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -282,9 +282,9 @@
Some must-read documents are:
\list
- \o \l{ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/pdf/GB18030_Summary.pdf}
- \o \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/source/gb18030/gb18030.html}
- \o \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/gb-18030-2000.xml}
+ \li \l{ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/pdf/GB18030_Summary.pdf}
+ \li \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/source/gb18030/gb18030.html}
+ \li \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/gb-18030-2000.xml}
\endlist
The GBK codec was contributed to Qt by
@@ -316,9 +316,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -354,30 +354,30 @@
\list
- \o "unicode-0.9" or "unicode-0201" for Unicode style. This assumes
+ \li "unicode-0.9" or "unicode-0201" for Unicode style. This assumes
JISX0201 for 0x00-0x7f. (0.9 is a table version of jisx02xx mapping
used for Unicode 1.1.)
- \o "unicode-ascii" This assumes US-ASCII for 0x00-0x7f; some
+ \li "unicode-ascii" This assumes US-ASCII for 0x00-0x7f; some
chars (JISX0208 0x2140 and JISX0212 0x2237) are different from
Unicode 1.1 to avoid conflict.
- \o "open-19970715-0201" ("open-0201" for convenience) or
+ \li "open-19970715-0201" ("open-0201" for convenience) or
"jisx0221-1995" for JISX0221-JISX0201 style. JIS X 0221 is JIS
version of Unicode, but a few chars (0x5c, 0x7e, 0x2140, 0x216f,
0x2131) are different from Unicode 1.1. This is used when 0x5c is
treated as YEN SIGN.
- \o "open-19970715-ascii" ("open-ascii" for convenience) for
+ \li "open-19970715-ascii" ("open-ascii" for convenience) for
JISX0221-ASCII style. This is used when 0x5c is treated as REVERSE
SOLIDUS.
- \o "open-19970715-ms" ("open-ms" for convenience) or "cp932" for
+ \li "open-19970715-ms" ("open-ms" for convenience) or "cp932" for
Microsoft Windows style. Windows Code Page 932. Some chars (0x2140,
0x2141, 0x2142, 0x215d, 0x2171, 0x2172) are different from Unicode
1.1.
- \o "jdk1.1.7" for Sun's JDK style. Same as Unicode 1.1, except that
+ \li "jdk1.1.7" for Sun's JDK style. Same as Unicode 1.1, except that
JIS 0x2140 is mapped to UFF3C. Either ASCII or JISX0201 can be used
for 0x00-0x7f.
@@ -405,9 +405,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -454,9 +454,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
@@ -510,9 +510,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\endlist
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 3119c4f661..f6f0cd8699 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -789,38 +789,38 @@ QTextCodec::ConverterState::~ConverterState()
The supported encodings are:
\list
- \o Apple Roman
- \o \l{Big5 Text Codec}{Big5}
- \o \l{Big5-HKSCS Text Codec}{Big5-HKSCS}
- \o CP949
- \o \l{EUC-JP Text Codec}{EUC-JP}
- \o \l{EUC-KR Text Codec}{EUC-KR}
- \o \l{GBK Text Codec}{GB18030-0}
- \o IBM 850
- \o IBM 866
- \o IBM 874
- \o \l{ISO 2022-JP (JIS) Text Codec}{ISO 2022-JP}
- \o ISO 8859-1 to 10
- \o ISO 8859-13 to 16
- \o Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
- \o JIS X 0201
- \o JIS X 0208
- \o KOI8-R
- \o KOI8-U
- \o MuleLao-1
- \o ROMAN8
- \o \l{Shift-JIS Text Codec}{Shift-JIS}
- \o TIS-620
- \o \l{TSCII Text Codec}{TSCII}
- \o UTF-8
- \o UTF-16
- \o UTF-16BE
- \o UTF-16LE
- \o UTF-32
- \o UTF-32BE
- \o UTF-32LE
- \o Windows-1250 to 1258
- \o WINSAMI2
+ \li Apple Roman
+ \li \l{Big5 Text Codec}{Big5}
+ \li \l{Big5-HKSCS Text Codec}{Big5-HKSCS}
+ \li CP949
+ \li \l{EUC-JP Text Codec}{EUC-JP}
+ \li \l{EUC-KR Text Codec}{EUC-KR}
+ \li \l{GBK Text Codec}{GB18030-0}
+ \li IBM 850
+ \li IBM 866
+ \li IBM 874
+ \li \l{ISO 2022-JP (JIS) Text Codec}{ISO 2022-JP}
+ \li ISO 8859-1 to 10
+ \li ISO 8859-13 to 16
+ \li Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
+ \li JIS X 0201
+ \li JIS X 0208
+ \li KOI8-R
+ \li KOI8-U
+ \li MuleLao-1
+ \li ROMAN8
+ \li \l{Shift-JIS Text Codec}{Shift-JIS}
+ \li TIS-620
+ \li \l{TSCII Text Codec}{TSCII}
+ \li UTF-8
+ \li UTF-16
+ \li UTF-16BE
+ \li UTF-16LE
+ \li UTF-32
+ \li UTF-32BE
+ \li UTF-32LE
+ \li Windows-1250 to 1258
+ \li WINSAMI2
\endlist
QTextCodecs can be used as follows to convert some locally encoded
@@ -871,29 +871,29 @@ QTextCodec::ConverterState::~ConverterState()
QTextCodec and implement the functions listed in the table below.
\table
- \header \o Function \o Description
+ \header \li Function \li Description
- \row \o name()
- \o Returns the official name for the encoding. If the
+ \row \li name()
+ \li Returns the official name for the encoding. If the
encoding is listed in the
\l{IANA character-sets encoding file}, the name
should be the preferred MIME name for the encoding.
- \row \o aliases()
- \o Returns a list of alternative names for the encoding.
+ \row \li aliases()
+ \li Returns a list of alternative names for the encoding.
QTextCodec provides a default implementation that returns
an empty list. For example, "ISO-8859-1" has "latin1",
"CP819", "IBM819", and "iso-ir-100" as aliases.
- \row \o mibEnum()
- \o Return the MIB enum for the encoding if it is listed in
+ \row \li mibEnum()
+ \li Return the MIB enum for the encoding if it is listed in
the \l{IANA character-sets encoding file}.
- \row \o convertToUnicode()
- \o Converts an 8-bit character string to Unicode.
+ \row \li convertToUnicode()
+ \li Converts an 8-bit character string to Unicode.
- \row \o convertFromUnicode()
- \o Converts a Unicode string to an 8-bit character string.
+ \row \li convertFromUnicode()
+ \li Converts a Unicode string to an 8-bit character string.
\endtable
\sa QTextStream, QTextDecoder, QTextEncoder, {Codecs Example}
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 6257376b62..a30250df81 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -892,13 +892,13 @@ bool qSharedBuild()
\brief The QSysInfo class provides information about the system.
\list
- \o \l WordSize specifies the size of a pointer for the platform
+ \li \l WordSize specifies the size of a pointer for the platform
on which the application is compiled.
- \o \l ByteOrder specifies whether the platform is big-endian or
+ \li \l ByteOrder specifies whether the platform is big-endian or
little-endian.
- \o \l WindowsVersion specifies the version of the Windows operating
+ \li \l WindowsVersion specifies the version of the Windows operating
system on which the application is run (Windows only)
- \o \l MacintoshVersion specifies the version of the Macintosh
+ \li \l MacintoshVersion specifies the version of the Macintosh
operating system on which the application is run (Mac only).
\endlist
@@ -2462,12 +2462,12 @@ int qrand()
\a Flags can be one of the following:
\list
- \o \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old
+ \li \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old
data) type with no constructor or destructor.
- \o \c Q_MOVABLE_TYPE specifies that \a Type has a constructor
+ \li \c Q_MOVABLE_TYPE specifies that \a Type has a constructor
and/or a destructor but can be moved in memory using \c
memcpy().
- \o \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
+ \li \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
constructors and/or a destructor and that it may not be moved
in memory.
\endlist
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index badccc947d..8cbd4528dc 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -309,7 +309,7 @@ QDebug QMessageLogger::critical()
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- If you are using the \bold{default message handler} this function will
+ If you are using the \b{default message handler} this function will
abort on Unix systems to create a core dump. On Windows, for debug builds,
this function will report a _CRT_ERROR enabling you to connect a debugger
to the application.
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 895feb7f53..1df36f42e6 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -266,7 +266,7 @@
This enum provides shorter names for the keyboard modifier keys
supported by Qt.
- \bold{Note:} On Mac OS X, the \c CTRL value corresponds to
+ \b{Note:} On Mac OS X, the \c CTRL value corresponds to
the Command keys on the Macintosh keyboard, and the \c META value
corresponds to the Control keys.
@@ -319,21 +319,21 @@
\table
\row
- \o \inlineimage qpen-solid.png
- \o \inlineimage qpen-dash.png
- \o \inlineimage qpen-dot.png
+ \li \inlineimage qpen-solid.png
+ \li \inlineimage qpen-dash.png
+ \li \inlineimage qpen-dot.png
\row
- \o Qt::SolidLine
- \o Qt::DashLine
- \o Qt::DotLine
+ \li Qt::SolidLine
+ \li Qt::DashLine
+ \li Qt::DotLine
\row
- \o \inlineimage qpen-dashdot.png
- \o \inlineimage qpen-dashdotdot.png
- \o \inlineimage qpen-custom.png
+ \li \inlineimage qpen-dashdot.png
+ \li \inlineimage qpen-dashdotdot.png
+ \li \inlineimage qpen-custom.png
\row
- \o Qt::DashDotLine
- \o Qt::DashDotDotLine
- \o Qt::CustomDashLine
+ \li Qt::DashDotLine
+ \li Qt::DashDotDotLine
+ \li Qt::CustomDashLine
\endtable
\value NoPen no line at all. For example, QPainter::drawRect()
@@ -360,13 +360,13 @@
\table
\row
- \o \inlineimage qpen-square.png
- \o \inlineimage qpen-flat.png
- \o \inlineimage qpen-roundcap.png
+ \li \inlineimage qpen-square.png
+ \li \inlineimage qpen-flat.png
+ \li \inlineimage qpen-roundcap.png
\row
- \o Qt::SquareCap
- \o Qt::FlatCap
- \o Qt::RoundCap
+ \li Qt::SquareCap
+ \li Qt::FlatCap
+ \li Qt::RoundCap
\endtable
\value FlatCap a square line end that does not cover the end
@@ -388,13 +388,13 @@
\table
\row
- \o \inlineimage qpen-bevel.png
- \o \inlineimage qpen-miter.png
- \o \inlineimage qpen-roundjoin.png
+ \li \inlineimage qpen-bevel.png
+ \li \inlineimage qpen-miter.png
+ \li \inlineimage qpen-roundjoin.png
\row
- \o Qt::BevelJoin
- \o Qt::MiterJoin
- \o Qt::RoundJoin
+ \li Qt::BevelJoin
+ \li Qt::MiterJoin
+ \li Qt::RoundJoin
\endtable
\value MiterJoin The outer edges of the lines are extended to
@@ -968,7 +968,7 @@
\value WA_NoSystemBackground Indicates that the widget has no background,
i.e. when the widget receives paint events, the background is not
automatically repainted. \note Unlike WA_OpaquePaintEvent, newly exposed
- areas are \bold never filled with the background (e.g., after showing a
+ areas are \b never filled with the background (e.g., after showing a
window for the first time the user can see "through" it until the
application processes the paint events). This flag is set or cleared by the
widget's author.
@@ -2653,7 +2653,7 @@
\value ElideNone Ellipsis should NOT appear in the text.
Qt::ElideMiddle is normally the most appropriate choice for URLs (e.g.,
- "\l{http://bugreports.qt.nokia.com/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"),
+ "\l{http://bugreports.qt-project.org/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"),
whereas Qt::ElideRight is appropriate
for other strings (e.g.,
"\l{http://qt.nokia.com/doc/qq/qq09-mac-deployment.html}{Deploying Applications on Ma...}").
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 6b5ecf73e1..851c18203d 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -61,63 +61,43 @@ QT_BEGIN_NAMESPACE
static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } };
static inline double qt_inf()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_inf_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes.d
: qt_le_inf_bytes.d);
-#endif
}
// Signaling NAN
static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_snan_bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } };
static inline double qt_snan()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_snan_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_snan_bytes.d
: qt_le_snan_bytes.d);
-#endif
}
// Quiet NAN
static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_qnan_bytes = { { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 } };
static inline double qt_qnan()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_qnan_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_qnan_bytes.d
: qt_le_qnan_bytes.d);
-#endif
}
#else // Q_CC_MIPS
static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
-static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
static inline double qt_inf()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_inf_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes
: qt_le_inf_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -127,17 +107,12 @@ static inline double qt_inf()
// Signaling NAN
static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
-static const unsigned char qt_armfpa_snan_bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
static inline double qt_snan()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_snan_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_snan_bytes
: qt_le_snan_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -147,17 +122,12 @@ static inline double qt_snan()
// Quiet NAN
static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff };
-static const unsigned char qt_armfpa_qnan_bytes[] = { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 };
static inline double qt_qnan()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_qnan_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_qnan_bytes
: qt_le_qnan_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -169,43 +139,31 @@ static inline double qt_qnan()
static inline bool qt_is_inf(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) == 0x7f && ch[2] == 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) == 0x7f && ch[1] == 0xf0;
} else {
return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0;
}
-#endif
}
static inline bool qt_is_nan(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) == 0x7f && ch[2] > 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) == 0x7f && ch[1] > 0xf0;
} else {
return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0;
}
-#endif
}
static inline bool qt_is_finite(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0xf0) != 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0xf0) != 0xf0;
} else {
return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0;
}
-#endif
}
static inline bool qt_is_inf(float d)
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index fd02f0e4c5..4213d5830e 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -53,16 +53,39 @@
The first is always defined. Defines for the various revisions/variants are
optional and usually dependent on how the compiler was invoked. Variants
that are a superset of another should have a define for the superset.
+
+ In addition to the procesor family, variants, and revisions, we also set
+ Q_BYTE_ORDER appropriately for the target processor. For bi-endian
+ processors, we try to auto-detect the byte order using the __BIG_ENDIAN__,
+ __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros.
*/
+/* Machine byte-order, reuse preprocessor provided macros when available */
+#if defined(__ORDER_BIG_ENDIAN__)
+# define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__
+#else
+# define Q_BIG_ENDIAN 4321
+#endif
+#if defined(__ORDER_LITTLE_ENDIAN__)
+# define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+#else
+# define Q_LITTLE_ENDIAN 1234
+#endif
+
/*
Alpha family, no revisions or variants
+
+ Alpha is bi-endian, use endianness auto-detection described above.
*/
// #elif defined(__alpha__) || defined(_M_ALPHA)
// # define Q_PROCESSOR_ALPHA
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
- ARM family, known revisions: V5, V6, and V7
+ ARM family, known revisions: V5, V6, and V7
+
+ ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
+ auto-detection described above.
*/
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
# define Q_PROCESSOR_ARM
@@ -88,37 +111,59 @@
|| (__TARGET_ARCH_ARM-0 >= 5)
# define Q_PROCESSOR_ARM_V5
# endif
+# if defined(__ARMEL__)
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# elif defined(__ARMEB__)
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+# else
+// Q_BYTE_ORDER not defined, use endianness auto-detection
+#endif
/*
AVR32 family, no revisions or variants
+
+ AVR32 is big-endian.
*/
// #elif defined(__avr32__)
// # define Q_PROCESSOR_AVR32
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
/*
Blackfin family, no revisions or variants
+
+ Blackfin is little-endian.
*/
// #elif defined(__bfin__)
// # define Q_PROCESSOR_BLACKFIN
+// # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
/*
X86 family, known variants: 32- and 64-bit
+
+ X86 is little-endian.
*/
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
# define Q_PROCESSOR_X86
# define Q_PROCESSOR_X86_32
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
# define Q_PROCESSOR_X86
# define Q_PROCESSOR_X86_64
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
/*
Itanium (IA-64) family, no revisions or variants
+
+ Itanium is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
# define Q_PROCESSOR_IA64
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
MIPS family, known revisions: I, II, III, IV, 32, 64
+
+ MIPS is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
# define Q_PROCESSOR_MIPS
@@ -143,6 +188,7 @@
# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
# define Q_PROCESSOR_MIPS_64
# endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
Power family, known variants: 32- and 64-bit
@@ -150,6 +196,8 @@
There are many more known variants/revisions that we do not handle/detect.
See http://en.wikipedia.org/wiki/Power_Architecture
and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg
+
+ Power is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
@@ -160,34 +208,60 @@
# else
# define Q_PROCESSOR_POWER_32
# endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
S390 family, known variant: S390X (64-bit)
+
+ S390 is big-endian.
*/
// #elif defined(__s390__)
// # define Q_PROCESSOR_S390
// # if defined(__s390x__)
// # define Q_PROCESSOR_S390_X
// # endif
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
/*
SuperH family, optional revision: SH-4A
+
+ SuperH is bi-endian, use endianness auto-detection descrived above.
*/
// #elif defined(__sh__)
// # define Q_PROCESSOR_SH
// # if defined(__sh4a__)
// # define Q_PROCESSOR_SH_4A
// # endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
SPARC family, optional revision: V9
+
+ SPARC is big-endian only prior to V9, while V9 is bi-endian with big-endian
+ as the default byte order. Assume all SPARC systems are big-endian.
*/
// #elif defined(__sparc__)
// # define Q_PROCESSOR_SPARC
// # if defined(__sparc_v9__)
// # define Q_PROCESSOR_SPARC_V9
// # endif
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
+
+#endif
+// Some processors support either endian format, try to detect which we are using.
+#if !defined(Q_BYTE_ORDER)
+# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN)
+// Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults
+# define Q_BYTE_ORDER __BYTE_ORDER__
+# elif defined(__BIG_ENDIAN__)
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+# elif defined(__LITTLE_ENDIAN__) \
+ || defined(Q_OS_WINCE) // Windows CE is always little-endian according to MSDN.
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# else
+# error "Unable to determine byte order!"
+# endif
#endif
#endif // QPROCESSORDETECTION_H
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 7920d881b4..1fe2a793a6 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -184,7 +184,7 @@ QT_BEGIN_NAMESPACE
\endcode
To see if your favorite Qt class has similar stream operators
- defined, check the \bold {Related Non-Members} section of the
+ defined, check the \b {Related Non-Members} section of the
class's documentation page.
\sa QTextStream QVariant
@@ -571,19 +571,19 @@ void QDataStream::setByteOrder(ByteOrder bo)
serialization format used by QDataStream.
\table
- \header \i Qt Version \i QDataStream Version
- \row \i Qt 4.6 \i 12
- \row \i Qt 4.5 \i 11
- \row \i Qt 4.4 \i 10
- \row \i Qt 4.3 \i 9
- \row \i Qt 4.2 \i 8
- \row \i Qt 4.0, 4.1 \i 7
- \row \i Qt 3.3 \i 6
- \row \i Qt 3.1, 3.2 \i 5
- \row \i Qt 3.0 \i 4
- \row \i Qt 2.1, 2.2, 2.3 \i 3
- \row \i Qt 2.0 \i 2
- \row \i Qt 1.x \i 1
+ \header \li Qt Version \li QDataStream Version
+ \row \li Qt 4.6 \li 12
+ \row \li Qt 4.5 \li 11
+ \row \li Qt 4.4 \li 10
+ \row \li Qt 4.3 \li 9
+ \row \li Qt 4.2 \li 8
+ \row \li Qt 4.0, 4.1 \li 7
+ \row \li Qt 3.3 \li 6
+ \row \li Qt 3.1, 3.2 \li 5
+ \row \li Qt 3.0 \li 4
+ \row \li Qt 2.1, 2.2, 2.3 \li 3
+ \row \li Qt 2.0 \li 2
+ \row \li Qt 1.x \li 1
\endtable
The \l Version enum provides symbolic constants for the different
@@ -771,10 +771,6 @@ QDataStream &QDataStream::operator>>(float &f)
return *this;
}
-#if defined(Q_DOUBLE_FORMAT)
-#define Q_DF(x) Q_DOUBLE_FORMAT[(x)] - '0'
-#endif
-
/*!
\overload
@@ -797,7 +793,6 @@ QDataStream &QDataStream::operator>>(double &f)
f = 0.0;
CHECK_STREAM_PRECOND(*this)
-#ifndef Q_DOUBLE_FORMAT
if (dev->read((char *)&f, 8) != 8) {
f = 0.0;
setStatus(ReadPastEnd);
@@ -811,39 +806,6 @@ QDataStream &QDataStream::operator>>(double &f)
f = x.val1;
}
}
-#else
- //non-standard floating point format
- union {
- double val1;
- char val2[8];
- } x;
- char *p = x.val2;
- char b[8];
- if (dev->read(b, 8) == 8) {
- if (noswap) {
- *p++ = b[Q_DF(0)];
- *p++ = b[Q_DF(1)];
- *p++ = b[Q_DF(2)];
- *p++ = b[Q_DF(3)];
- *p++ = b[Q_DF(4)];
- *p++ = b[Q_DF(5)];
- *p++ = b[Q_DF(6)];
- *p = b[Q_DF(7)];
- } else {
- *p++ = b[Q_DF(7)];
- *p++ = b[Q_DF(6)];
- *p++ = b[Q_DF(5)];
- *p++ = b[Q_DF(4)];
- *p++ = b[Q_DF(3)];
- *p++ = b[Q_DF(2)];
- *p++ = b[Q_DF(1)];
- *p = b[Q_DF(0)];
- }
- f = x.val1;
- } else {
- setStatus(ReadPastEnd);
- }
-#endif
return *this;
}
@@ -1112,7 +1074,6 @@ QDataStream &QDataStream::operator<<(double f)
}
CHECK_STREAM_WRITE_PRECOND(*this)
-#ifndef Q_DOUBLE_FORMAT
if (noswap) {
if (dev->write((char *)&f, sizeof(double)) != sizeof(double))
q_status = WriteFailed;
@@ -1126,36 +1087,6 @@ QDataStream &QDataStream::operator<<(double f)
if (dev->write((char *)&x.val2, sizeof(double)) != sizeof(double))
q_status = WriteFailed;
}
-#else
- union {
- double val1;
- char val2[8];
- } x;
- x.val1 = f;
- char *p = x.val2;
- char b[8];
- if (noswap) {
- b[Q_DF(0)] = *p++;
- b[Q_DF(1)] = *p++;
- b[Q_DF(2)] = *p++;
- b[Q_DF(3)] = *p++;
- b[Q_DF(4)] = *p++;
- b[Q_DF(5)] = *p++;
- b[Q_DF(6)] = *p++;
- b[Q_DF(7)] = *p;
- } else {
- b[Q_DF(7)] = *p++;
- b[Q_DF(6)] = *p++;
- b[Q_DF(5)] = *p++;
- b[Q_DF(4)] = *p++;
- b[Q_DF(3)] = *p++;
- b[Q_DF(2)] = *p++;
- b[Q_DF(1)] = *p++;
- b[Q_DF(0)] = *p;
- }
- if (dev->write(b, 8) != 8)
- q_status = WriteFailed;
-#endif
return *this;
}
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index afd402d019..1dedc7c5c8 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -451,11 +451,11 @@ inline void QDirPrivate::initFileEngine()
for these that return strings:
\table
- \header \o QDir \o QString \o Return Value
- \row \o current() \o currentPath() \o The application's working directory
- \row \o home() \o homePath() \o The user's home directory
- \row \o root() \o rootPath() \o The root directory
- \row \o temp() \o tempPath() \o The system's temporary directory
+ \header \li QDir \li QString \li Return Value
+ \row \li current() \li currentPath() \li The application's working directory
+ \row \li home() \li homePath() \li The user's home directory
+ \row \li root() \li rootPath() \li The root directory
+ \row \li temp() \li tempPath() \li The system's temporary directory
\endtable
The setCurrent() static function can also be used to set the application's
@@ -1878,13 +1878,13 @@ QString QDir::currentPath()
the given order) until an existing and available path is found:
\list 1
- \o The path specified by the \c USERPROFILE environment variable.
- \o The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
+ \li The path specified by the \c USERPROFILE environment variable.
+ \li The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
environment variables.
- \o The path specified by the \c HOME environment variable.
- \o The path returned by the rootPath() function (which uses the \c SystemDrive
+ \li The path specified by the \c HOME environment variable.
+ \li The path returned by the rootPath() function (which uses the \c SystemDrive
environment variable)
- \o The \c{C:/} directory.
+ \li The \c{C:/} directory.
\endlist
Under non-Windows operating systems the \c HOME environment
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index fc0c90cf69..6640dca70b 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -1034,13 +1034,13 @@ bool QFile::open(OpenMode mode)
then calling close() closes the adopted handle.
Otherwise, close() does not actually close the file, but only flushes it.
- \bold{Warning:}
+ \b{Warning:}
\list 1
- \o If \a fh does not refer to a regular file, e.g., it is \c stdin,
+ \li If \a fh does not refer to a regular file, e.g., it is \c stdin,
\c stdout, or \c stderr, you may not be able to seek(). size()
returns \c 0 in those cases. See QIODevice::isSequential() for
more information.
- \o Since this function opens the file without specifying the file name,
+ \li Since this function opens the file without specifying the file name,
you cannot use this QFile with a QFileInfo.
\endlist
@@ -1048,7 +1048,7 @@ bool QFile::open(OpenMode mode)
\sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
- \bold{Note for the Windows Platform}
+ \b{Note for the Windows Platform}
\a fh must be opened in binary mode (i.e., the mode string must contain
'b', as in "rb" or "wb") when accessing files and other random-access
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index a7fb0fb6c7..044c71d00a 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -812,7 +812,7 @@ QString QFileInfo::suffix() const
/*!
Returns the path of the object's parent directory as a QDir object.
- \bold{Note:} The QDir returned always corresponds to the object's
+ \b{Note:} The QDir returned always corresponds to the object's
parent directory, even if the QFileInfo represents a directory.
For each of the following, dir() returns a QDir for
@@ -901,7 +901,7 @@ bool QFileInfo::isExecutable() const
/*!
Returns true if this is a `hidden' file; otherwise returns false.
- \bold{Note:} This function returns true for the special entries
+ \b{Note:} This function returns true for the special entries
"." and ".." on Unix, even though QDir::entryList threats them as shown.
*/
bool QFileInfo::isHidden() const
@@ -923,7 +923,7 @@ bool QFileInfo::isHidden() const
Returns false if the file is otherwise supported by a virtual file system
inside Qt, such as \l{the Qt Resource System}.
- \bold{Note:} Native paths may still require conversion of path separators
+ \b{Note:} Native paths may still require conversion of path separators
and character encoding, depending on platform and input requirements of the
native API.
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 3d9391ebaa..1cdfc61627 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -163,12 +163,12 @@ QIODevicePrivate::~QIODevicePrivate()
random-access devices and sequential devices.
\list
- \o Random-access devices support seeking to arbitrary
+ \li Random-access devices support seeking to arbitrary
positions using seek(). The current position in the file is
available by calling pos(). QFile and QBuffer are examples of
random-access devices.
- \o Sequential devices don't support seeking to arbitrary
+ \li Sequential devices don't support seeking to arbitrary
positions. The data must be read in one pass. The functions
pos() and size() don't work for sequential devices.
QTcpSocket and QProcess are examples of sequential devices.
@@ -199,14 +199,14 @@ QIODevicePrivate::~QIODevicePrivate()
a separate thread:
\list
- \o waitForReadyRead() - This function suspends operation in the
+ \li waitForReadyRead() - This function suspends operation in the
calling thread until new data is available for reading.
- \o waitForBytesWritten() - This function suspends operation in the
+ \li waitForBytesWritten() - This function suspends operation in the
calling thread until one payload of data has been written to the
device.
- \o waitFor....() - Subclasses of QIODevice implement blocking
+ \li waitFor....() - Subclasses of QIODevice implement blocking
functions for device-specific operations. For example, QProcess
has a function called waitForStarted() which suspends operation in
the calling thread until the process has started.
@@ -1038,9 +1038,9 @@ QByteArray QIODevice::readAll()
Data is read until either of the following conditions are met:
\list
- \o The first '\n' character is read.
- \o \a maxSize - 1 bytes are read.
- \o The end of the device data is detected.
+ \li The first '\n' character is read.
+ \li \a maxSize - 1 bytes are read.
+ \li The end of the device data is detected.
\endlist
For example, the following code reads a line of characters from a
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 7a81313fa0..640704ec86 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -532,15 +532,15 @@ void QProcessPrivate::Channel::clear()
certain signals are emitted:
\list
- \o waitForStarted() blocks until the process has started.
+ \li waitForStarted() blocks until the process has started.
- \o waitForReadyRead() blocks until new data is
+ \li waitForReadyRead() blocks until new data is
available for reading on the current read channel.
- \o waitForBytesWritten() blocks until one payload of
+ \li waitForBytesWritten() blocks until one payload of
data has been written to the process.
- \o waitForFinished() blocks until the process has finished.
+ \li waitForFinished() blocks until the process has finished.
\endlist
Calling these functions from the main thread (the thread that
@@ -1910,7 +1910,7 @@ QByteArray QProcess::readAllStandardError()
\note No further splitting of the arguments is performed.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
\sa pid(), started(), waitForStarted()
*/
@@ -2149,10 +2149,10 @@ int QProcess::execute(const QString &program)
Note that arguments that contain spaces are not passed to the
process as separate arguments.
- \bold{Unix:} The started process will run in its own session and act
+ \b{Unix:} The started process will run in its own session and act
like a daemon.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
The started process will run as a regular standalone process.
The process will be started in the directory \a workingDirectory.
@@ -2183,10 +2183,10 @@ bool QProcess::startDetached(const QString &program,
\note Arguments that contain spaces are not passed to the
process as separate arguments.
- \bold{Unix:} The started process will run in its own session and act
+ \b{Unix:} The started process will run in its own session and act
like a daemon.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
The started process will run as a regular standalone process.
*/
bool QProcess::startDetached(const QString &program,
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index e46ab260b0..fb3a24b940 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -114,7 +114,7 @@ class QResourceRoot
};
const uchar *tree, *names, *payloads;
inline int findOffset(int node) const { return node * 14; } //sizeof each tree element
- int hash(int node) const;
+ uint hash(int node) const;
QString name(int node) const;
short flags(int node) const;
public:
@@ -594,7 +594,7 @@ QResource::searchPaths()
return *resourceSearchPaths();
}
-inline int QResourceRoot::hash(int node) const
+inline uint QResourceRoot::hash(int node) const
{
if(!node) //root
return 0;
@@ -673,13 +673,13 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const
qDebug() << " " << child+j << " :: " << name(child+j);
}
#endif
- const int h = qHash(segment);
+ const uint h = qHash(segment);
//do the binary search for the hash
int l = 0, r = child_count-1;
int sub_node = (l+r+1)/2;
while(r != l) {
- const int sub_node_hash = hash(child+sub_node);
+ const uint sub_node_hash = hash(child+sub_node);
if(h == sub_node_hash)
break;
else if(h < sub_node_hash)
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index f743c592bd..1ec0390235 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2112,15 +2112,15 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
avoid portability problems, follow these simple rules:
\list 1
- \o Always refer to the same key using the same case. For example,
+ \li Always refer to the same key using the same case. For example,
if you refer to a key as "text fonts" in one place in your
code, don't refer to it as "Text Fonts" somewhere else.
- \o Avoid key names that are identical except for the case. For
+ \li Avoid key names that are identical except for the case. For
example, if you have a key called "MainWindow", don't try to
save another key as "mainwindow".
- \o Do not use slashes ('/' and '\\') in section or key names; the
+ \li Do not use slashes ('/' and '\\') in section or key names; the
backslash character is used to separate sub keys (see below). On
windows '\\' are converted by QSettings to '/', which makes
them identical.
@@ -2156,10 +2156,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
that order:
\list 1
- \o a user-specific location for the Star Runner application
- \o a user-specific location for all applications by MySoft
- \o a system-wide location for the Star Runner application
- \o a system-wide location for all applications by MySoft
+ \li a user-specific location for the Star Runner application
+ \li a user-specific location for all applications by MySoft
+ \li a system-wide location for the Star Runner application
+ \li a system-wide location for all applications by MySoft
\endlist
(See \l{Platform-Specific Notes} below for information on what
@@ -2184,17 +2184,17 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet doc/src/snippets/settings/settings.cpp 14
The table below summarizes which QSettings objects access
- which location. "\bold{X}" means that the location is the main
+ which location. "\b{X}" means that the location is the main
location associated to the QSettings object and is used both
for reading and for writing; "o" means that the location is used
as a fallback when reading.
\table
- \header \o Locations \o \c{obj1} \o \c{obj2} \o \c{obj3} \o \c{obj4}
- \row \o 1. User, Application \o \bold{X} \o \o \o
- \row \o 2. User, Organization \o o \o \bold{X} \o \o
- \row \o 3. System, Application \o o \o \o \bold{X} \o
- \row \o 4. System, Organization \o o \o o \o o \o \bold{X}
+ \header \li Locations \li \c{obj1} \li \c{obj2} \li \c{obj3} \li \c{obj4}
+ \row \li 1. User, Application \li \b{X} \li \li \li
+ \row \li 2. User, Organization \li o \li \b{X} \li \li
+ \row \li 3. System, Application \li o \li \li \b{X} \li
+ \row \li 4. System, Organization \li o \li o \li o \li \b{X}
\endtable
The beauty of this mechanism is that it works on all platforms
@@ -2276,30 +2276,30 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
following files are used by default:
\list 1
- \o \c{$HOME/.config/MySoft/Star Runner.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.conf})
- \o \c{$HOME/.config/MySoft.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.conf})
- \o \c{/etc/xdg/MySoft/Star Runner.conf}
- \o \c{/etc/xdg/MySoft.conf}
+ \li \c{$HOME/.config/MySoft/Star Runner.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.conf})
+ \li \c{$HOME/.config/MySoft.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.conf})
+ \li \c{/etc/xdg/MySoft/Star Runner.conf}
+ \li \c{/etc/xdg/MySoft.conf}
\endlist
On Mac OS X versions 10.2 and 10.3, these files are used by
default:
\list 1
- \o \c{$HOME/Library/Preferences/com.MySoft.Star Runner.plist}
- \o \c{$HOME/Library/Preferences/com.MySoft.plist}
- \o \c{/Library/Preferences/com.MySoft.Star Runner.plist}
- \o \c{/Library/Preferences/com.MySoft.plist}
+ \li \c{$HOME/Library/Preferences/com.MySoft.Star Runner.plist}
+ \li \c{$HOME/Library/Preferences/com.MySoft.plist}
+ \li \c{/Library/Preferences/com.MySoft.Star Runner.plist}
+ \li \c{/Library/Preferences/com.MySoft.plist}
\endlist
On Windows, NativeFormat settings are stored in the following
registry paths:
\list 1
- \o \c{HKEY_CURRENT_USER\Software\MySoft\Star Runner}
- \o \c{HKEY_CURRENT_USER\Software\MySoft}
- \o \c{HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner}
- \o \c{HKEY_LOCAL_MACHINE\Software\MySoft}
+ \li \c{HKEY_CURRENT_USER\Software\MySoft\Star Runner}
+ \li \c{HKEY_CURRENT_USER\Software\MySoft}
+ \li \c{HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner}
+ \li \c{HKEY_LOCAL_MACHINE\Software\MySoft}
\endlist
\note On Windows, for 32-bit programs running in WOW64 mode, settings are
@@ -2310,19 +2310,19 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
used on Unix and Mac OS X:
\list 1
- \o \c{$HOME/.config/MySoft/Star Runner.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.ini})
- \o \c{$HOME/.config/MySoft.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.ini})
- \o \c{/etc/xdg/MySoft/Star Runner.ini}
- \o \c{/etc/xdg/MySoft.ini}
+ \li \c{$HOME/.config/MySoft/Star Runner.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.ini})
+ \li \c{$HOME/.config/MySoft.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.ini})
+ \li \c{/etc/xdg/MySoft/Star Runner.ini}
+ \li \c{/etc/xdg/MySoft.ini}
\endlist
On Windows, the following files are used:
\list 1
- \o \c{%APPDATA%\MySoft\Star Runner.ini}
- \o \c{%APPDATA%\MySoft.ini}
- \o \c{%COMMON_APPDATA%\MySoft\Star Runner.ini}
- \o \c{%COMMON_APPDATA%\MySoft.ini}
+ \li \c{%APPDATA%\MySoft\Star Runner.ini}
+ \li \c{%APPDATA%\MySoft.ini}
+ \li \c{%COMMON_APPDATA%\MySoft\Star Runner.ini}
+ \li \c{%COMMON_APPDATA%\MySoft.ini}
\endlist
The \c %APPDATA% path is usually \tt{C:\\Documents and
@@ -2395,20 +2395,20 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
application:
\list
- \o The Windows system registry has the following limitations: A
+ \li The Windows system registry has the following limitations: A
subkey may not exceed 255 characters, an entry's value may
not exceed 16,383 characters, and all the values of a key may
not exceed 65,535 characters. One way to work around these
limitations is to store the settings using the IniFormat
instead of the NativeFormat.
- \o On Mac OS X, allKeys() will return some extra keys for global
+ \li On Mac OS X, allKeys() will return some extra keys for global
settings that apply to all applications. These keys can be
read using value() but cannot be changed, only shadowed.
Calling setFallbacksEnabled(false) will hide these global
settings.
- \o On Mac OS X, the CFPreferences API used by QSettings expects
+ \li On Mac OS X, the CFPreferences API used by QSettings expects
Internet domain names rather than organization names. To
provide a uniform API, QSettings derives a fake domain name
from the organization name (unless the organization name
@@ -2425,7 +2425,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet doc/src/snippets/code/src_corelib_io_qsettings.cpp 7
- \o On Unix and Mac OS X systems, the advisory file locking is disabled
+ \li On Unix and Mac OS X systems, the advisory file locking is disabled
if NFS (or AutoFS or CacheFS) is detected to work around a bug in the
NFS fcntl() implementation, which hangs forever if statd or lockd aren't
running. Also, the locking isn't performed when accessing \c .plist
@@ -2485,7 +2485,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
follow what Microsoft does, with the following exceptions:
\list
- \o If you store types that QVariant can't convert to QString
+ \li If you store types that QVariant can't convert to QString
(e.g., QPoint, QRect, and QSize), Qt uses an \c{@}-based
syntax to encode the type. For example:
@@ -2496,7 +2496,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
followed by a Qt type (\c Point, \c Rect, \c Size, etc.) is
treated as a normal character.
- \o Although backslash is a special character in INI files, most
+ \li Although backslash is a special character in INI files, most
Windows applications don't escape backslashes (\c{\}) in file
paths:
@@ -2505,7 +2505,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
QSettings always treats backslash as a special character and
provides no API for reading or writing such entries.
- \o The INI file format has severe restrictions on the syntax of
+ \li The INI file format has severe restrictions on the syntax of
a key. Qt works around this by using \c % as an escape
character in keys. In addition, if you save a top-level
setting (a key with no slashes in it, e.g., "someKey"), it
@@ -2514,7 +2514,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
such as "General/someKey", the key will be located in the
"%General" section, \e not in the "General" section.
- \o Following the philosophy that we should be liberal in what
+ \li Following the philosophy that we should be liberal in what
we accept and conservative in what we generate, QSettings
will accept Latin-1 encoded INI files, but generate pure
ASCII files, where non-ASCII values are encoded using standard
@@ -2632,10 +2632,10 @@ QSettings::QSettings(Format format, Scope scope, const QString &organization,
be aware of the following limitations:
\list
- \o QSettings provides no way of reading INI "path" entries, i.e., entries
+ \li QSettings provides no way of reading INI "path" entries, i.e., entries
with unescaped slash characters. (This is because these entries are
ambiguous and cannot be resolved automatically.)
- \o In INI files, QSettings uses the \c @ character as a metacharacter in some
+ \li In INI files, QSettings uses the \c @ character as a metacharacter in some
contexts, to encode Qt-specific data types (e.g., \c @Rect), and might
therefore misinterpret it when it occurs in pure INI files.
\endlist
@@ -2933,9 +2933,9 @@ QSettings::Status QSettings::status() const
This will set the value of three settings:
\list
- \o \c mainwindow/size
- \o \c mainwindow/fullScreen
- \o \c outputpanel/visible
+ \li \c mainwindow/size
+ \li \c mainwindow/fullScreen
+ \li \c outputpanel/visible
\endlist
Call endGroup() to reset the current group to what it was before
@@ -3021,14 +3021,14 @@ int QSettings::beginReadArray(const QString &prefix)
The generated keys will have the form
\list
- \o \c logins/size
- \o \c logins/1/userName
- \o \c logins/1/password
- \o \c logins/2/userName
- \o \c logins/2/password
- \o \c logins/3/userName
- \o \c logins/3/password
- \o ...
+ \li \c logins/size
+ \li \c logins/1/userName
+ \li \c logins/1/password
+ \li \c logins/2/userName
+ \li \c logins/2/password
+ \li \c logins/3/userName
+ \li \c logins/3/password
+ \li ...
\endlist
To read back an array, use beginReadArray().
@@ -3412,15 +3412,15 @@ void QSettings::setUserIniPath(const QString &dir)
The table below summarizes the default values:
\table
- \header \o Platform \o Format \o Scope \o Path
- \row \o{1,2} Windows \o{1,2} IniFormat \o UserScope \o \c %APPDATA%
- \row \o SystemScope \o \c %COMMON_APPDATA%
- \row \o{1,2} Unix \o{1,2} NativeFormat, IniFormat \o UserScope \o \c $HOME/.config
- \row \o SystemScope \o \c /etc/xdg
- \row \o{1,2} Qt for Embedded Linux \o{1,2} NativeFormat, IniFormat \o UserScope \o \c $HOME/Settings
- \row \o SystemScope \o \c /etc/xdg
- \row \o{1,2} Mac OS X \o{1,2} IniFormat \o UserScope \o \c $HOME/.config
- \row \o SystemScope \o \c /etc/xdg
+ \header \li Platform \li Format \li Scope \li Path
+ \row \li{1,2} Windows \li{1,2} IniFormat \li UserScope \li \c %APPDATA%
+ \row \li SystemScope \li \c %COMMON_APPDATA%
+ \row \li{1,2} Unix \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/.config
+ \row \li SystemScope \li \c /etc/xdg
+ \row \li{1,2} Qt for Embedded Linux \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/Settings
+ \row \li SystemScope \li \c /etc/xdg
+ \row \li{1,2} Mac OS X \li{1,2} IniFormat \li UserScope \li \c $HOME/.config
+ \row \li SystemScope \li \c /etc/xdg
\endtable
The default UserScope paths on Unix and Mac OS X (\c
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index dd0ab85119..cb703df8c6 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -90,13 +90,13 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
\list
- \o Chunk by chunk, by calling readLine() or readAll().
+ \li Chunk by chunk, by calling readLine() or readAll().
- \o Word by word. QTextStream supports streaming into QStrings,
+ \li Word by word. QTextStream supports streaming into QStrings,
QByteArrays and char* buffers. Words are delimited by space, and
leading white space is automatically skipped.
- \o Character by character, by streaming into QChar or char types.
+ \li Character by character, by streaming into QChar or char types.
This method is often used for convenient input handling when
parsing files, independent of character encoding and end-of-line
semantics. To skip white space, call skipWhiteSpace().
@@ -134,31 +134,31 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
defines several global manipulator functions:
\table
- \header \o Manipulator \o Description
- \row \o \c bin \o Same as setIntegerBase(2).
- \row \o \c oct \o Same as setIntegerBase(8).
- \row \o \c dec \o Same as setIntegerBase(10).
- \row \o \c hex \o Same as setIntegerBase(16).
- \row \o \c showbase \o Same as setNumberFlags(numberFlags() | ShowBase).
- \row \o \c forcesign \o Same as setNumberFlags(numberFlags() | ForceSign).
- \row \o \c forcepoint \o Same as setNumberFlags(numberFlags() | ForcePoint).
- \row \o \c noshowbase \o Same as setNumberFlags(numberFlags() & ~ShowBase).
- \row \o \c noforcesign \o Same as setNumberFlags(numberFlags() & ~ForceSign).
- \row \o \c noforcepoint \o Same as setNumberFlags(numberFlags() & ~ForcePoint).
- \row \o \c uppercasebase \o Same as setNumberFlags(numberFlags() | UppercaseBase).
- \row \o \c uppercasedigits \o Same as setNumberFlags(numberFlags() | UppercaseDigits).
- \row \o \c lowercasebase \o Same as setNumberFlags(numberFlags() & ~UppercaseBase).
- \row \o \c lowercasedigits \o Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
- \row \o \c fixed \o Same as setRealNumberNotation(FixedNotation).
- \row \o \c scientific \o Same as setRealNumberNotation(ScientificNotation).
- \row \o \c left \o Same as setFieldAlignment(AlignLeft).
- \row \o \c right \o Same as setFieldAlignment(AlignRight).
- \row \o \c center \o Same as setFieldAlignment(AlignCenter).
- \row \o \c endl \o Same as operator<<('\n') and flush().
- \row \o \c flush \o Same as flush().
- \row \o \c reset \o Same as reset().
- \row \o \c ws \o Same as skipWhiteSpace().
- \row \o \c bom \o Same as setGenerateByteOrderMark(true).
+ \header \li Manipulator \li Description
+ \row \li \c bin \li Same as setIntegerBase(2).
+ \row \li \c oct \li Same as setIntegerBase(8).
+ \row \li \c dec \li Same as setIntegerBase(10).
+ \row \li \c hex \li Same as setIntegerBase(16).
+ \row \li \c showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
+ \row \li \c forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
+ \row \li \c forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
+ \row \li \c noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
+ \row \li \c noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
+ \row \li \c noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
+ \row \li \c uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
+ \row \li \c uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
+ \row \li \c lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
+ \row \li \c lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
+ \row \li \c fixed \li Same as setRealNumberNotation(FixedNotation).
+ \row \li \c scientific \li Same as setRealNumberNotation(ScientificNotation).
+ \row \li \c left \li Same as setFieldAlignment(AlignLeft).
+ \row \li \c right \li Same as setFieldAlignment(AlignRight).
+ \row \li \c center \li Same as setFieldAlignment(AlignCenter).
+ \row \li \c endl \li Same as operator<<('\n') and flush().
+ \row \li \c flush \li Same as flush().
+ \row \li \c reset \li Same as reset().
+ \row \li \c ws \li Same as skipWhiteSpace().
+ \row \li \c bom \li Same as setGenerateByteOrderMark(true).
\endtable
In addition, Qt provides three global manipulators that take a
@@ -2065,12 +2065,12 @@ QTextStream &QTextStream::operator>>(char &c)
number using the following rules:
\table
- \header \o Prefix \o Base
- \row \o "0b" or "0B" \o 2 (binary)
- \row \o "0" followed by "0-7" \o 8 (octal)
- \row \o "0" otherwise \o 10 (decimal)
- \row \o "0x" or "0X" \o 16 (hexadecimal)
- \row \o "1" to "9" \o 10 (decimal)
+ \header \li Prefix \li Base
+ \row \li "0b" or "0B" \li 2 (binary)
+ \row \li "0" followed by "0-7" \li 8 (octal)
+ \row \li "0" otherwise \li 10 (decimal)
+ \row \li "0x" or "0X" \li 16 (hexadecimal)
+ \row \li "1" to "9" \li 10 (decimal)
\endtable
By calling setIntegerBase(), you can specify the integer base
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index eeeca1bf77..0659053937 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -112,7 +112,7 @@
dealing with URLs and strings:
\list
- \o When creating an QString to contain a URL from a QByteArray or a
+ \li When creating an QString to contain a URL from a QByteArray or a
char*, always use QString::fromUtf8().
\endlist
@@ -135,15 +135,15 @@
\list
- \o Spaces and "%20": If an encoded URL contains a space, this will be
+ \li Spaces and "%20": If an encoded URL contains a space, this will be
replaced with "%20". If a decoded URL contains "%20", this will be
replaced with a single space before the URL is parsed.
- \o Single "%" characters: Any occurrences of a percent character "%" not
+ \li Single "%" characters: Any occurrences of a percent character "%" not
followed by exactly two hexadecimal characters (e.g., "13% coverage.html")
will be replaced by "%25".
- \o Reserved and unreserved characters: An encoded URL should only
+ \li Reserved and unreserved characters: An encoded URL should only
contain a few characters as literals; all other characters should
be percent-encoded. In TolerantMode, these characters will be
automatically percent-encoded where they are not allowed:
@@ -6335,10 +6335,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\section1 Examples:
\list
- \o qt.nokia.com becomes http://qt.nokia.com
- \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
- \o hostname becomes http://hostname
- \o /home/user/test.html becomes file:///home/user/test.html
+ \li qt.nokia.com becomes http://qt.nokia.com
+ \li ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
+ \li hostname becomes http://hostname
+ \li /home/user/test.html becomes file:///home/user/test.html
\endlist
*/
QUrl QUrl::fromUserInput(const QString &userInput)
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index a8c3921f45..7a1357959e 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1161,16 +1161,16 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
\e before and \e after they occur:
\list
- \o An insertRows() implementation must call beginInsertRows() \e before
+ \li An insertRows() implementation must call beginInsertRows() \e before
inserting new rows into the data structure, and endInsertRows()
\e{immediately afterwards}.
- \o An insertColumns() implementation must call beginInsertColumns()
+ \li An insertColumns() implementation must call beginInsertColumns()
\e before inserting new columns into the data structure, and
endInsertColumns() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows() \e before
+ \li A removeRows() implementation must call beginRemoveRows() \e before
the rows are removed from the data structure, and endRemoveRows()
\e{immediately afterwards}.
- \o A removeColumns() implementation must call beginRemoveColumns()
+ \li A removeColumns() implementation must call beginRemoveColumns()
\e before the columns are removed from the data structure, and
endRemoveColumns() \e{immediately afterwards}.
\endlist
@@ -1179,7 +1179,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
the chance to take action before any data becomes unavailable. The
encapsulation of the insert and remove operations with these begin and end
functions also enables the model to manage \l{QPersistentModelIndex}
- {persistent model indexes} correctly. \bold{If you want selections to be
+ {persistent model indexes} correctly. \b{If you want selections to be
handled properly, you must ensure that you call these functions.} If you
insert or remove an item with children, you do not need to call these
functions for the child items. In other words, the parent item will take
@@ -1338,11 +1338,11 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
layoutChanged(). In other words, when the structure changes:
\list
- \o emit layoutAboutToBeChanged
- \o Remember the QModelIndex that will change
- \o Update your internal data
- \o Call changePersistentIndex()
- \o emit layoutChanged
+ \li emit layoutAboutToBeChanged
+ \li Remember the QModelIndex that will change
+ \li Update your internal data
+ \li Call changePersistentIndex()
+ \li emit layoutChanged
\endlist
\sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), modelReset(),
@@ -1500,7 +1500,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item have been moved to \a destinationParent
starting at the row \a destinationRow.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1516,7 +1516,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
starting at the row \a destinationRow.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1532,7 +1532,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item have been moved to \a destinationParent
starting at the column \a destinationColumn.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1548,7 +1548,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
starting at the column \a destinationColumn.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1683,7 +1683,7 @@ bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value
Returns the data stored under the given \a role for the item referred to
by the \a index.
- \note If you do not have a value to return, return an \bold invalid
+ \note If you do not have a value to return, return an \b invalid
QVariant instead of returning 0.
\sa Qt::ItemDataRole, setData(), headerData()
@@ -2437,8 +2437,8 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare
\table 80%
\row
- \o \inlineimage modelview-begin-insert-rows.png Inserting rows
- \o Specify the first and last row numbers for the span of rows you
+ \li \inlineimage modelview-begin-insert-rows.png Inserting rows
+ \li Specify the first and last row numbers for the span of rows you
want to insert into an item in a model.
For example, as shown in the diagram, we insert three rows before
@@ -2448,8 +2448,8 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare
This inserts the three new rows as rows 2, 3, and 4.
\row
- \o \inlineimage modelview-begin-append-rows.png Appending rows
- \o To append rows, insert them after the last row.
+ \li \inlineimage modelview-begin-append-rows.png Appending rows
+ \li To append rows, insert them after the last row.
For example, as shown in the diagram, we append two rows to a
collection of 4 existing rows (ending in row 3), so \a first is 4
@@ -2503,8 +2503,8 @@ void QAbstractItemModel::endInsertRows()
\table 80%
\row
- \o \inlineimage modelview-begin-remove-rows.png Removing rows
- \o Specify the first and last row numbers for the span of rows you
+ \li \inlineimage modelview-begin-remove-rows.png Removing rows
+ \li Specify the first and last row numbers for the span of rows you
want to remove from an item in a model.
For example, as shown in the diagram, we remove the two rows from
@@ -2616,8 +2616,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
\table 80%
\row
- \o \inlineimage modelview-move-rows-1.png Moving rows to another parent
- \o Specify the first and last row numbers for the span of rows in
+ \li \inlineimage modelview-move-rows-1.png Moving rows to another parent
+ \li Specify the first and last row numbers for the span of rows in
the source parent you want to move in the model. Also specify
the row in the destination parent to move the span to.
@@ -2630,8 +2630,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
the destination. Other affected siblings are displaced accordingly.
\row
- \o \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
- \o To append rows to another parent, move them to after the last row.
+ \li \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
+ \li To append rows to another parent, move them to after the last row.
For example, as shown in the diagram, we move three rows to a
collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
@@ -2640,8 +2640,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
This moves the target rows to the end of the target parent as 6, 7 and 8.
\row
- \o \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
- \o To move rows within the same parent, specify the row to move them to.
+ \li \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
+ \li To move rows within the same parent, specify the row to move them to.
For example, as shown in the diagram, we move one item from row 2 to row 0,
so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
@@ -2655,8 +2655,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
it is already)
\row
- \o \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
- \o To move rows within the same parent, specify the row to move them to.
+ \li \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
+ \li To move rows within the same parent, specify the row to move them to.
For example, as shown in the diagram, we move one item from row 2 to row 4,
so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
@@ -2737,8 +2737,8 @@ void QAbstractItemModel::endMoveRows()
\table 80%
\row
- \o \inlineimage modelview-begin-insert-columns.png Inserting columns
- \o Specify the first and last column numbers for the span of columns
+ \li \inlineimage modelview-begin-insert-columns.png Inserting columns
+ \li Specify the first and last column numbers for the span of columns
you want to insert into an item in a model.
For example, as shown in the diagram, we insert three columns
@@ -2748,8 +2748,8 @@ void QAbstractItemModel::endMoveRows()
This inserts the three new columns as columns 4, 5, and 6.
\row
- \o \inlineimage modelview-begin-append-columns.png Appending columns
- \o To append columns, insert them after the last column.
+ \li \inlineimage modelview-begin-append-columns.png Appending columns
+ \li To append columns, insert them after the last column.
For example, as shown in the diagram, we append three columns to a
collection of six existing columns (ending in column 5), so
@@ -2805,8 +2805,8 @@ void QAbstractItemModel::endInsertColumns()
\table 80%
\row
- \o \inlineimage modelview-begin-remove-columns.png Removing columns
- \o Specify the first and last column numbers for the span of columns
+ \li \inlineimage modelview-begin-remove-columns.png Removing columns
+ \li Specify the first and last column numbers for the span of columns
you want to remove from an item in a model.
For example, as shown in the diagram, we remove the three columns
@@ -3135,16 +3135,16 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const
are aware of any changes:
\list
- \o An insertRows() implementation must call beginInsertRows()
+ \li An insertRows() implementation must call beginInsertRows()
\e before inserting new rows into the data structure, and it must
call endInsertRows() \e{immediately afterwards}.
- \o An insertColumns() implementation must call beginInsertColumns()
+ \li An insertColumns() implementation must call beginInsertColumns()
\e before inserting new columns into the data structure, and it must
call endInsertColumns() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows()
+ \li A removeRows() implementation must call beginRemoveRows()
\e before the rows are removed from the data structure, and it must
call endRemoveRows() \e{immediately afterwards}.
- \o A removeColumns() implementation must call beginRemoveColumns()
+ \li A removeColumns() implementation must call beginRemoveColumns()
\e before the columns are removed from the data structure, and it must
call endRemoveColumns() \e{immediately afterwards}.
\endlist
@@ -3271,10 +3271,10 @@ bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
functions so that all connected views are aware of any changes:
\list
- \o An insertRows() implementation must call beginInsertRows()
+ \li An insertRows() implementation must call beginInsertRows()
\e before inserting new rows into the data structure, and it must
call endInsertRows() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows()
+ \li A removeRows() implementation must call beginRemoveRows()
\e before the rows are removed from the data structure, and it must
call endRemoveRows() \e{immediately afterwards}.
\endlist
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index b7ef69423f..ae9affb862 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -2531,16 +2531,16 @@ void QSortFilterProxyModel::invalidateFilter()
the following QVariant types:
\list
- \o QVariant::Int
- \o QVariant::UInt
- \o QVariant::LongLong
- \o QVariant::ULongLong
- \o QVariant::Double
- \o QVariant::Char
- \o QVariant::Date
- \o QVariant::Time
- \o QVariant::DateTime
- \o QVariant::String
+ \li QVariant::Int
+ \li QVariant::UInt
+ \li QVariant::LongLong
+ \li QVariant::ULongLong
+ \li QVariant::Double
+ \li QVariant::Char
+ \li QVariant::Date
+ \li QVariant::Time
+ \li QVariant::DateTime
+ \li QVariant::String
\endlist
Any other type will be converted to a QString using
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 55c37988e2..0742ced39b 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -309,6 +309,7 @@ public:
{
d->length = str.length();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ const qle_ushort *uc = (const qle_ushort *)str.unicode();
for (int i = 0; i < str.length(); ++i)
d->utf16[i] = uc[i];
#else
@@ -359,7 +360,7 @@ public:
QString str(l, Qt::Uninitialized);
QChar *ch = str.data();
for (int i = 0; i < l; ++i)
- ch[i] = d->utf16[i];
+ ch[i] = QChar(d->utf16[i]);
return str;
#endif
}
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index 6ffb9639f7..433a68105d 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -560,7 +560,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
/*! \typedef QJsonArray::iterator::iterator_category
- A synonym for \i {std::random_access_iterator_tag} indicating
+ A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a random access iterator.
*/
@@ -794,7 +794,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
/*! \typedef QJsonArray::const_iterator::iterator_category
- A synonym for \i {std::random_access_iterator_tag} indicating
+ A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a random access iterator.
*/
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index 289a752c8b..cfe71e8959 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -569,7 +569,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::iterator::iterator_category
- A synonym for \i {std::bidirectional_iterator_tag} indicating
+ A synonym for \e {std::bidirectional_iterator_tag} indicating
this iterator is a bidirectional iterator.
*/
@@ -758,7 +758,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::const_iterator::iterator_category
- A synonym for \i {std::bidirectional_iterator_tag} indicating
+ A synonym for \e {std::bidirectional_iterator_tag} indicating
this iterator is a bidirectional iterator.
*/
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 603cba8897..b4a689da60 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -64,12 +64,12 @@ QT_BEGIN_NAMESPACE
JSON is a format to store structured data. It has 6 basic data types:
\list
- \o bool QJsonValue::Bool
- \o double QJsonValue::Double
- \o string QJsonValue::String
- \o array QJsonValue::Array
- \o object QJsonValue::Object
- \o null QJsonValue::Null
+ \li bool QJsonValue::Bool
+ \li double QJsonValue::Double
+ \li string QJsonValue::String
+ \li array QJsonValue::Array
+ \li object QJsonValue::Object
+ \li null QJsonValue::Null
\endlist
A value can represent any of the above data types. In addition, QJsonValue has one special
@@ -260,16 +260,16 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other)
The conversion will convert QVariant types as follows:
\list
- \o QVariant::Bool to Bool
- \o QVariant::Int
- \o QVariant::Double
- \o QVariant::LongLong
- \o QVariant::ULongLong
- \o QVariant::UInt to Double
- \o QVariant::String to String
- \o QVariant::StringList
- \o QVariant::VariantList to Array
- \o QVariant::VariantMap to Object
+ \li QVariant::Bool to Bool
+ \li QVariant::Int
+ \li QVariant::Double
+ \li QVariant::LongLong
+ \li QVariant::ULongLong
+ \li QVariant::UInt to Double
+ \li QVariant::String to String
+ \li QVariant::StringList
+ \li QVariant::VariantList to Array
+ \li QVariant::VariantMap to Object
\endlist
For all other QVariant types a conversion to a QString will be attempted. If the returned string
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 3075eab753..b98f3f4a30 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -167,7 +167,7 @@ QAbstractEventDispatcher::~QAbstractEventDispatcher()
event dispatcher exists for the specified thread, this function
returns 0.
- \bold{Note:} If Qt is built without thread support, the \a thread
+ \b{Note:} If Qt is built without thread support, the \a thread
argument is ignored.
*/
QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
@@ -192,10 +192,10 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
\list
- \i If events are available, this function returns after processing
+ \li If events are available, this function returns after processing
them.
- \i If no events are available, this function will wait until more
+ \li If no events are available, this function will wait until more
are available and return after processing newly available events.
\endlist
@@ -204,7 +204,7 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
and no events are available, this function will return
immediately.
- \bold{Note:} This function does not process events continuously; it
+ \b{Note:} This function does not process events continuously; it
returns after all available events are processed.
\sa hasPendingEvents()
@@ -349,17 +349,17 @@ void QAbstractEventDispatcher::closingDown()
\table
\header
- \o Platform
- \o type
+ \li Platform
+ \li type
\row
- \o Windows
- \o MSG
+ \li Windows
+ \li MSG
\row
- \o X11
- \o XEvent
+ \li X11
+ \li XEvent
\row
- \o Mac
- \o NSEvent
+ \li Mac
+ \li NSEvent
\endtable
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 78cb0eff3b..048d746183 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -57,17 +57,6 @@
# define __IMAGECAPTURE__
#endif
-#undef OLD_DEBUG
-#ifdef DEBUG
-# define OLD_DEBUG DEBUG
-# undef DEBUG
-#endif
-#define DEBUG 0
-#ifdef qDebug
-# define old_qDebug qDebug
-# undef qDebug
-#endif
-
#if defined(QT_BUILD_QMAKE) || defined(QT_BOOTSTRAPPED)
#include <ApplicationServices/ApplicationServices.h>
#else
@@ -82,18 +71,6 @@
#include <Foundation/Foundation.h>
#endif
-#undef DEBUG
-#ifdef OLD_DEBUG
-# define DEBUG OLD_DEBUG
-# undef OLD_DEBUG
-#endif
-
-#ifdef old_qDebug
-# undef qDebug
-# define qDebug QT_NO_QDEBUG_MACRO
-# undef old_qDebug
-#endif
-
#include "qstring.h"
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 2d49b271ce..515732bc68 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -715,13 +715,13 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
reimplementing this virtual function is just one of them. All five
approaches are listed below:
\list 1
- \i Reimplementing paintEvent(), mousePressEvent() and so
+ \li Reimplementing paintEvent(), mousePressEvent() and so
on. This is the commonest, easiest and least powerful way.
- \i Reimplementing this function. This is very powerful, providing
+ \li Reimplementing this function. This is very powerful, providing
complete control; but only one subclass can be active at a time.
- \i Installing an event filter on QCoreApplication::instance(). Such
+ \li Installing an event filter on QCoreApplication::instance(). Such
an event filter is able to process all events for all widgets, so
it's just as powerful as reimplementing notify(); furthermore, it's
possible to have more than one application-global event filter.
@@ -730,11 +730,11 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
event filters are only called for objects that live in the main
thread.
- \i Reimplementing QObject::event() (as QWidget does). If you do
+ \li Reimplementing QObject::event() (as QWidget does). If you do
this you get Tab key presses, and you get to see the events before
any widget-specific event filters.
- \i Installing an event filter on the object. Such an event filter gets all
+ \li Installing an event filter on the object. Such an event filter gets all
the events, including Tab and Shift+Tab key press events, as long as they
do not change the focus widget.
\endlist
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index dfdd178c35..58e2c5cd2f 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -222,11 +222,11 @@ int QEventLoop::exec(ProcessEventsFlags flags)
operation and want to show its progress without allowing user
input, i.e. by using the \l ExcludeUserInputEvents flag.
- \bold{Notes:}
+ \b{Notes:}
\list
- \o This function does not process events continuously; it
+ \li This function does not process events continuously; it
returns after all available events are processed.
- \o Specifying the \l WaitForMoreEvents flag makes no sense
+ \li Specifying the \l WaitForMoreEvents flag makes no sense
and will be ignored.
\endlist
*/
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index d53ba707f7..f962fb7831 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -86,16 +86,16 @@ QT_BEGIN_NAMESPACE
The functions you are most likely to find useful are these:
\list
- \o className() returns the name of a class.
- \o superClass() returns the superclass's meta-object.
- \o method() and methodCount() provide information
+ \li className() returns the name of a class.
+ \li superClass() returns the superclass's meta-object.
+ \li method() and methodCount() provide information
about a class's meta-methods (signals, slots and other
\l{Q_INVOKABLE}{invokable} member functions).
- \o enumerator() and enumeratorCount() and provide information about
+ \li enumerator() and enumeratorCount() and provide information about
a class's enumerators.
- \o propertyCount() and property() provide information about a
+ \li propertyCount() and property() provide information about a
class's properties.
- \o constructor() and constructorCount() provide information
+ \li constructor() and constructorCount() provide information
about a class's meta-constructors.
\endlist
@@ -1051,18 +1051,18 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
depending on \a type:
\list
- \o If \a type is Qt::DirectConnection, the member will be invoked immediately.
+ \li If \a type is Qt::DirectConnection, the member will be invoked immediately.
- \o If \a type is Qt::QueuedConnection,
+ \li If \a type is Qt::QueuedConnection,
a QEvent will be sent and the member is invoked as soon as the application
enters the main event loop.
- \o If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
+ \li If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
the same way as for Qt::QueuedConnection, except that the current thread
will block until the event is delivered. Using this connection type to
communicate between objects in the same thread will lead to deadlocks.
- \o If \a type is Qt::AutoConnection, the member is invoked
+ \li If \a type is Qt::AutoConnection, the member is invoked
synchronously if \a obj lives in the same thread as the
caller; otherwise it will invoke the member asynchronously.
\endlist
@@ -1456,13 +1456,13 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
\a connectionType:
\list
- \o If \a connectionType is Qt::DirectConnection, the member will be invoked immediately.
+ \li If \a connectionType is Qt::DirectConnection, the member will be invoked immediately.
- \o If \a connectionType is Qt::QueuedConnection,
+ \li If \a connectionType is Qt::QueuedConnection,
a QEvent will be posted and the member is invoked as soon as the application
enters the main event loop.
- \o If \a connectionType is Qt::AutoConnection, the member is invoked
+ \li If \a connectionType is Qt::AutoConnection, the member is invoked
synchronously if \a object lives in the same thread as the
caller; otherwise it will invoke the member asynchronously.
\endlist
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index cfe985da26..3a3464e43e 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -246,12 +246,12 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
functions to access the data:
\table
- \header \o Tester \o Getter \o Setter \o MIME Types
- \row \o hasText() \o text() \o setText() \o \c text/plain
- \row \o hasHtml() \o html() \o setHtml() \o \c text/html
- \row \o hasUrls() \o urls() \o setUrls() \o \c text/uri-list
- \row \o hasImage() \o imageData() \o setImageData() \o \c image/ *
- \row \o hasColor() \o colorData() \o setColorData() \o \c application/x-color
+ \header \li Tester \li Getter \li Setter \li MIME Types
+ \row \li hasText() \li text() \li setText() \li \c text/plain
+ \row \li hasHtml() \li html() \li setHtml() \li \c text/html
+ \row \li hasUrls() \li urls() \li setUrls() \li \c text/uri-list
+ \row \li hasImage() \li imageData() \li setImageData() \li \c image/ *
+ \row \li hasColor() \li colorData() \li setColorData() \li \c application/x-color
\endtable
For example, if your write a widget that accepts URL drags, you
@@ -263,15 +263,15 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
object:
\list 1
- \o Custom data can be stored directly in a QMimeData object as a
+ \li Custom data can be stored directly in a QMimeData object as a
QByteArray using setData(). For example:
\snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 1
- \o We can subclass QMimeData and reimplement hasFormat(),
+ \li We can subclass QMimeData and reimplement hasFormat(),
formats(), and retrieveData().
- \o If the drag and drop operation occurs within a single
+ \li If the drag and drop operation occurs within a single
application, we can subclass QMimeData and add extra data in
it, and use a qobject_cast() in the receiver's drop event
handler. For example:
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 2231518253..19440e9368 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1815,7 +1815,7 @@ void QObject::removeEventFilter(QObject *obj)
deleted, the control must return to the event loop from which
deleteLater() was called.
- \bold{Note:} It is safe to call this function more than once; when the
+ \b{Note:} It is safe to call this function more than once; when the
first deferred deletion event is delivered, any pending events for the
object are removed from the event queue.
@@ -2133,9 +2133,9 @@ int QObject::receivers(const char *signal) const
member in the specified class.
\list
- \o If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+ \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
- \o If specified member is not a member of obj instance class (or one of
+ \li If specified member is not a member of obj instance class (or one of
its parent classes) then both signalIndex and methodIndex are set to -1.
\endlist
@@ -2515,7 +2515,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
disconnect() is typically used in three ways, as the following
examples demonstrate.
\list 1
- \i Disconnect everything connected to an object's signals:
+ \li Disconnect everything connected to an object's signals:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
@@ -2523,7 +2523,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 27
- \i Disconnect everything connected to a specific signal:
+ \li Disconnect everything connected to a specific signal:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 28
@@ -2531,7 +2531,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 29
- \i Disconnect a specific receiver:
+ \li Disconnect a specific receiver:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
@@ -2673,11 +2673,11 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
if:
\list 1
- \i \a signal is not a member of sender class or one of its parent classes.
+ \li \a signal is not a member of sender class or one of its parent classes.
- \i \a method is not a member of receiver class or one of its parent classes.
+ \li \a method is not a member of receiver class or one of its parent classes.
- \i \a signal instance represents not a signal.
+ \li \a signal instance represents not a signal.
\endlist
@@ -3349,7 +3349,7 @@ int QObjectPrivate::signalIndex(const char *signalName) const
Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent
to be sent to the object.
- \bold{Note:} Dynamic properties starting with "_q_" are reserved for internal
+ \b{Note:} Dynamic properties starting with "_q_" are reserved for internal
purposes.
\sa property(), metaObject(), dynamicPropertyNames()
@@ -4101,19 +4101,19 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
disconnect() is typically used in three ways, as the following
examples demonstrate.
\list 1
- \i Disconnect everything connected to an object's signals:
+ \li Disconnect everything connected to an object's signals:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
- \i Disconnect everything connected to a specific signal:
+ \li Disconnect everything connected to a specific signal:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 47
- \i Disconnect a specific receiver:
+ \li Disconnect a specific receiver:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
- \i Disconnect a connection from one specific signal to a specific slot:
+ \li Disconnect a connection from one specific signal to a specific slot:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 48
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 5f43b52939..9f09617071 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -198,6 +198,10 @@ public:
inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
+#ifdef Q_QDOC
+ QMetaObject::Connection QObject::connect(const QObject *sender, (T::*signal)(...), const QObject *receiver, (T::*method)(...), Qt::ConnectionType type)
+ QMetaObject::Connection QObject::connect(const QObject *sender, (T::*signal)(...), Functor functor)
+#else
//Connect a signal to a pointer to qobject member function
template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
@@ -261,6 +265,7 @@ public:
new QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot),
Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
}
+#endif //Q_QDOC
static bool disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member);
@@ -273,6 +278,9 @@ public:
{ return disconnect(this, 0, receiver, member); }
static bool disconnect(const QMetaObject::Connection &);
+#ifdef Q_QDOC
+ bool QObject::disconnect(const QObject *sender, (T::*signal)(...), const Qbject *receiver, (T::*method)(...))
+#else
template <typename Func1, typename Func2>
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot)
@@ -300,6 +308,7 @@ public:
return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, zero,
&SignalType::Object::staticMetaObject);
}
+#endif //Q_QDOC
void dumpObjectTree();
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index f75d4464b2..c8edadce9d 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -275,8 +275,9 @@ private:
class QBoolBlocker
{
+ Q_DISABLE_COPY(QBoolBlocker)
public:
- inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
+ explicit inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
inline ~QBoolBlocker(){block = reset; }
private:
bool &block;
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index fa0226917f..4b3829b53e 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -65,8 +65,10 @@ class QString;
# if defined(QT_NO_KEYWORDS)
# define QT_NO_EMIT
# else
-# define slots
-# define signals public
+# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
+# define slots
+# define signals public
+# endif
# endif
# define Q_SLOTS
# define Q_SIGNALS public
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index 936a933d2d..b983bef5fe 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -61,13 +61,13 @@
\list
- \i When using QPointer on a QWidget (or a subclass of QWidget), previously
+ \li When using QPointer on a QWidget (or a subclass of QWidget), previously
the QPointer would be cleared by the QWidget destructor. Now, the QPointer
is cleared by the QObject destructor (since this is when QWeakPointers are
cleared). Any QPointers tracking a widget will \b NOT be cleared before the
QWidget destructor destroys the children for the widget being tracked.
- \i When constructing a QSharedPointer to take ownership of an object after a
+ \li When constructing a QSharedPointer to take ownership of an object after a
QPointer is already tracking the object. Previously, the shared pointer
construction would not be affected by the QPointer, but now that QPointer
is implemented using QWeakPoiner, constructing the QSharedPointer will
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 640dfc0f94..d8578a8059 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -100,13 +100,13 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
\list
- \o Windows: QSharedMemory does not "own" the shared memory segment.
+ \li Windows: QSharedMemory does not "own" the shared memory segment.
When all threads or processes that have an instance of QSharedMemory
attached to a particular shared memory segment have either destroyed
their instance of QSharedMemory or exited, the Windows kernel
releases the shared memory segment automatically.
- \o Unix: QSharedMemory "owns" the shared memory segment. When the
+ \li Unix: QSharedMemory "owns" the shared memory segment. When the
last thread or process that has an instance of QSharedMemory
attached to a particular shared memory segment detaches from the
segment by destroying its instance of QSharedMemory, the Unix kernel
@@ -114,7 +114,7 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
process crashes without running the QSharedMemory destructor, the
shared memory segment survives the crash.
- \o HP-UX: Only one attach to a shared memory segment is allowed per
+ \li HP-UX: Only one attach to a shared memory segment is allowed per
process. This means that QSharedMemory should not be used across
multiple threads in the same process in HP-UX.
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index d7689bb7b1..0a2a66b6b2 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -111,9 +111,9 @@ QT_BEGIN_NAMESPACE
follow these steps when you receive a notification:
\list 1
- \o Disable the notifier.
- \o Read data from the socket.
- \o Re-enable the notifier if you are interested in more data (such as after
+ \li Disable the notifier.
+ \li Read data from the socket.
+ \li Re-enable the notifier if you are interested in more data (such as after
having written a new command to a remote server).
\endlist
@@ -121,12 +121,12 @@ QT_BEGIN_NAMESPACE
follow these steps when you receive a notification:
\list 1
- \o Disable the notifier.
- \o Write as much data as you can (before \c EWOULDBLOCK is returned).
- \o Re-enable notifier if you have more data to write.
+ \li Disable the notifier.
+ \li Write as much data as you can (before \c EWOULDBLOCK is returned).
+ \li Re-enable notifier if you have more data to write.
\endlist
- \bold{Further information:}
+ \b{Further information:}
On Windows, Qt always disables the notifier after getting a notification,
and only re-enables it if more data is expected. For example, if data is
read from the socket and it can be used to read more, or if reading or
@@ -162,7 +162,7 @@ QT_BEGIN_NAMESPACE
It is generally advisable to explicitly enable or disable the
socket notifier, especially for write notifiers.
- \bold{Note for Windows users:} The socket passed to QSocketNotifier
+ \b{Note for Windows users:} The socket passed to QSocketNotifier
will become non-blocking, even if it was created as a blocking socket.
\sa setEnabled(), isEnabled()
diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp
index d0a67834dd..0558f3cb59 100644
--- a/src/corelib/kernel/qsystemsemaphore.cpp
+++ b/src/corelib/kernel/qsystemsemaphore.cpp
@@ -90,16 +90,16 @@ QT_BEGIN_NAMESPACE
When using this class, be aware of the following platform
differences:
- \bold{Windows:} QSystemSemaphore does not own its underlying system
+ \b{Windows:} QSystemSemaphore does not own its underlying system
semaphore. Windows owns it. This means that when all instances of
QSystemSemaphore for a particular key have been destroyed, either by
having their destructors called, or because one or more processes
crash, Windows removes the underlying system semaphore.
- \bold{Unix:}
+ \b{Unix:}
\list
- \o QSystemSemaphore owns the underlying system semaphore
+ \li QSystemSemaphore owns the underlying system semaphore
in Unix systems. This means that the last process having an instance of
QSystemSemaphore for a particular key must remove the underlying
system semaphore in its destructor. If the last process crashes
@@ -117,7 +117,7 @@ QT_BEGIN_NAMESPACE
{QSystemSemaphore::} {Create}, which will force Unix to reset the
resource count in the underlying system semaphore.
- \o When a process using QSystemSemaphore terminates for
+ \li When a process using QSystemSemaphore terminates for
any reason, Unix automatically reverses the effect of all acquire
operations that were not released. Thus if the process acquires a
resource and then exits without releasing it, Unix will release that
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index a11bcb26c9..dad3318870 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -279,9 +279,9 @@ public:
up to three parameters:
\list
- \o The \e context - usually the class name for the tr() caller.
- \o The \e {source text} - usually the argument to tr().
- \o The \e disambiguation - an optional string that helps disambiguate
+ \li The \e context - usually the class name for the tr() caller.
+ \li The \e {source text} - usually the argument to tr().
+ \li The \e disambiguation - an optional string that helps disambiguate
different uses of the same text in the same context.
\endlist
@@ -361,12 +361,12 @@ QTranslator::~QTranslator()
in the following order:
\list 1
- \o File name without \a suffix appended.
- \o File name with text after a character in \a search_delimiters
+ \li File name without \a suffix appended.
+ \li File name with text after a character in \a search_delimiters
stripped ("_." is the default for \a search_delimiters if it is
an empty string) and \a suffix.
- \o File name stripped without \a suffix appended.
- \o File name stripped further, etc.
+ \li File name stripped without \a suffix appended.
+ \li File name stripped further, etc.
\endlist
For example, an application running in the fr_CA locale
@@ -375,12 +375,12 @@ QTranslator::~QTranslator()
readable file from this list:
\list 1
- \o \c /opt/foolib/foo.fr_ca.qm
- \o \c /opt/foolib/foo.fr_ca
- \o \c /opt/foolib/foo.fr.qm
- \o \c /opt/foolib/foo.fr
- \o \c /opt/foolib/foo.qm
- \o \c /opt/foolib/foo
+ \li \c /opt/foolib/foo.fr_ca.qm
+ \li \c /opt/foolib/foo.fr_ca
+ \li \c /opt/foolib/foo.fr.qm
+ \li \c /opt/foolib/foo.fr
+ \li \c /opt/foolib/foo.qm
+ \li \c /opt/foolib/foo
\endlist
*/
@@ -599,10 +599,10 @@ static QString find_translation(const QLocale & locale,
in the following order:
\list 1
- \o File name without \a suffix appended.
- \o File name with ui language part after a "_" character stripped and \a suffix.
- \o File name with ui language part stripped without \a suffix appended.
- \o File name with ui language part stripped further, etc.
+ \li File name without \a suffix appended.
+ \li File name with ui language part after a "_" character stripped and \a suffix.
+ \li File name with ui language part stripped without \a suffix appended.
+ \li File name with ui language part stripped further, etc.
\endlist
For example, an application running in the locale with the following
@@ -612,17 +612,17 @@ static QString find_translation(const QLocale & locale,
open the first existing readable file from this list:
\list 1
- \o \c /opt/foolib/foo.es.qm
- \o \c /opt/foolib/foo.es
- \o \c /opt/foolib/foo.fr_CA.qm
- \o \c /opt/foolib/foo.fr_CA
- \o \c /opt/foolib/foo.de.qm
- \o \c /opt/foolib/foo.de
- \o \c /opt/foolib/foo.fr.qm
- \o \c /opt/foolib/foo.fr
- \o \c /opt/foolib/foo.qm
- \o \c /opt/foolib/foo.
- \o \c /opt/foolib/foo
+ \li \c /opt/foolib/foo.es.qm
+ \li \c /opt/foolib/foo.es
+ \li \c /opt/foolib/foo.fr_CA.qm
+ \li \c /opt/foolib/foo.fr_CA
+ \li \c /opt/foolib/foo.de.qm
+ \li \c /opt/foolib/foo.de
+ \li \c /opt/foolib/foo.fr.qm
+ \li \c /opt/foolib/foo.fr
+ \li \c /opt/foolib/foo.qm
+ \li \c /opt/foolib/foo.
+ \li \c /opt/foolib/foo
\endlist
On operating systems where file system is case sensitive, QTranslator also
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 5eaa93c7b0..029a261faf 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2174,7 +2174,7 @@ inline T qNumVariantToHelper(const QVariant::Private &d,
If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
converted to an int; otherwise \c{*}\a{ok} is set to false.
- \bold{Warning:} If the value is convertible to a \l LongLong but is too
+ \b{Warning:} If the value is convertible to a \l LongLong but is too
large to be represented in an int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toInt().
Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
@@ -2194,7 +2194,7 @@ int QVariant::toInt(bool *ok) const
If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
- \bold{Warning:} If the value is convertible to a \l ULongLong but is too
+ \b{Warning:} If the value is convertible to a \l ULongLong but is too
large to be represented in an unsigned int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toUInt().
Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
@@ -2411,28 +2411,28 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
The following casts are done automatically:
\table
- \header \o Type \o Automatically Cast To
- \row \o \l Bool \o \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l ByteArray \o \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l Char \o \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
- \row \o \l Color \o \l String
- \row \o \l Date \o \l DateTime, \l String
- \row \o \l DateTime \o \l Date, \l String, \l Time
- \row \o \l Double \o \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l Font \o \l String
- \row \o \l Int \o \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l KeySequence \o \l Int, \l String
- \row \o \l List \o \l StringList (if the list's items can be converted to strings)
- \row \o \l LongLong \o \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
- \row \o \l Point \o PointF
- \row \o \l Rect \o RectF
- \row \o \l String \o \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
+ \header \li Type \li Automatically Cast To
+ \row \li \l Bool \li \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l ByteArray \li \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l Char \li \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
+ \row \li \l Color \li \l String
+ \row \li \l Date \li \l DateTime, \l String
+ \row \li \l DateTime \li \l Date, \l String, \l Time
+ \row \li \l Double \li \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l Font \li \l String
+ \row \li \l Int \li \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l KeySequence \li \l Int, \l String
+ \row \li \l List \li \l StringList (if the list's items can be converted to strings)
+ \row \li \l LongLong \li \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
+ \row \li \l Point \li PointF
+ \row \li \l Rect \li RectF
+ \row \li \l String \li \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
\l Font, \l Int, \l KeySequence, \l LongLong, \l StringList, \l Time, \l UInt,
\l ULongLong
- \row \o \l StringList \o \l List, \l String (if the list contains exactly one item)
- \row \o \l Time \o \l String
- \row \o \l UInt \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
- \row \o \l ULongLong \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
+ \row \li \l StringList \li \l List, \l String (if the list contains exactly one item)
+ \row \li \l Time \li \l String
+ \row \li \l UInt \li \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
+ \row \li \l ULongLong \li \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
\endtable
\sa convert()
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 11a2dc83f5..58ca046d9d 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE
Finally, you can use the setHandle() function to register a new event
object, and the handle() function to retrieve the event handle.
- \bold{Further information:}
+ \b{Further information:}
Although the class is called QWinEventNotifier, it can be used for
certain other objects which are so-called synchronization
objects, such as Processes, Threads, Waitable timers.
@@ -140,7 +140,7 @@ QWinEventNotifier::~QWinEventNotifier()
Register the HANDLE \a hEvent. The old HANDLE will be automatically
unregistered.
- \bold Note: The notifier will be disabled as a side effect and needs
+ \b Note: The notifier will be disabled as a side effect and needs
to be re-enabled.
\sa handle(), setEnabled()
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index b171577184..216e6e1e7c 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -596,12 +596,12 @@ bool QLibraryPrivate::loadPlugin()
library; otherwise returns false.
\table
- \header \i Platform \i Valid suffixes
- \row \i Windows \i \c .dll, \c .DLL
- \row \i Unix/Linux \i \c .so
- \row \i AIX \i \c .a
- \row \i HP-UX \i \c .sl, \c .so (HP-UXi)
- \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so
+ \header \li Platform \li Valid suffixes
+ \row \li Windows \li \c .dll, \c .DLL
+ \row \li Unix/Linux \li \c .so
+ \row \li AIX \li \c .a
+ \row \li HP-UX \li \c .sl, \c .so (HP-UXi)
+ \row \li Mac OS X \li \c .dylib, \c .bundle, \c .so
\endtable
Trailing versioning numbers on Unix are ignored.
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index d652b251f1..f198f108da 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -66,9 +66,9 @@ QT_BEGIN_NAMESPACE
using QLibrary:
\list
- \o QPluginLoader checks that a plugin is linked against the same
+ \li QPluginLoader checks that a plugin is linked against the same
version of Qt as the application.
- \o QPluginLoader provides direct access to a root component object
+ \li QPluginLoader provides direct access to a root component object
(instance()), instead of forcing you to resolve a C function manually.
\endlist
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 3d7988a8fc..26032323e0 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -190,34 +190,34 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
\table
\header
- \o msb0
- \o msb1
- \o msb2
- \o Variant
+ \li msb0
+ \li msb1
+ \li msb2
+ \li Variant
\row
- \o 0
- \o x
- \o x
- \o NCS (Network Computing System)
+ \li 0
+ \li x
+ \li x
+ \li NCS (Network Computing System)
\row
- \o 1
- \o 0
- \o x
- \o DCE (Distributed Computing Environment)
+ \li 1
+ \li 0
+ \li x
+ \li DCE (Distributed Computing Environment)
\row
- \o 1
- \o 1
- \o 0
- \o Microsoft (GUID)
+ \li 1
+ \li 1
+ \li 0
+ \li Microsoft (GUID)
\row
- \o 1
- \o 1
- \o 1
- \o Reserved for future expansion
+ \li 1
+ \li 1
+ \li 1
+ \li Reserved for future expansion
\endtable
@@ -234,46 +234,46 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
\table
\header
- \o msb0
- \o msb1
- \o msb2
- \o msb3
- \o Version
+ \li msb0
+ \li msb1
+ \li msb2
+ \li msb3
+ \li Version
\row
- \o 0
- \o 0
- \o 0
- \o 1
- \o Time
+ \li 0
+ \li 0
+ \li 0
+ \li 1
+ \li Time
\row
- \o 0
- \o 0
- \o 1
- \o 0
- \o Embedded POSIX
+ \li 0
+ \li 0
+ \li 1
+ \li 0
+ \li Embedded POSIX
\row
- \o 0
- \o 0
- \o 1
- \o 1
- \o Md5(Name)
+ \li 0
+ \li 0
+ \li 1
+ \li 1
+ \li Md5(Name)
\row
- \o 0
- \o 1
- \o 0
- \o 0
- \o Random
+ \li 0
+ \li 1
+ \li 0
+ \li 0
+ \li Random
\row
- \o 0
- \o 1
- \o 0
- \o 1
- \o Sha1
+ \li 0
+ \li 1
+ \li 0
+ \li 1
+ \li Sha1
\endtable
@@ -516,28 +516,28 @@ QUuid QUuid::fromRfc4122(const QByteArray &bytes)
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[1]
+ \li 4
+ \li data4[0] .. data4[1]
\row
- \o 5
- \o data4[2] .. data4[7]
+ \li 5
+ \li data4[2] .. data4[7]
\endtable
*/
@@ -560,28 +560,28 @@ QString QUuid::toString() const
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[1]
+ \li 4
+ \li data4[0] .. data4[1]
\row
- \o 5
- \o data4[2] .. data4[7]
+ \li 5
+ \li data4[2] .. data4[7]
\endtable
@@ -607,24 +607,24 @@ QByteArray QUuid::toByteArray() const
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[7]
+ \li 4
+ \li data4[0] .. data4[7]
\endtable
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 5443d6e1b6..2e3029f3fa 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -83,16 +83,16 @@
\list
- \o Relaxed - memory ordering is unspecified, leaving the compiler
+ \li Relaxed - memory ordering is unspecified, leaving the compiler
and processor to freely reorder memory accesses.
- \o Acquire - memory access following the atomic operation (in
+ \li Acquire - memory access following the atomic operation (in
program order) may not be re-ordered before the atomic operation.
- \o Release - memory access before the atomic operation (in program
+ \li Release - memory access before the atomic operation (in program
order) may not be re-ordered after the atomic operation.
- \o Ordered - the same Acquire and Release semantics combined.
+ \li Ordered - the same Acquire and Release semantics combined.
\endlist
@@ -180,25 +180,25 @@
\list
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
\endlist
@@ -658,16 +658,16 @@
\list
- \o Relaxed - memory ordering is unspecified, leaving the compiler
+ \li Relaxed - memory ordering is unspecified, leaving the compiler
and processor to freely reorder memory accesses.
- \o Acquire - memory access following the atomic operation (in
+ \li Acquire - memory access following the atomic operation (in
program order) may not be re-ordered before the atomic operation.
- \o Release - memory access before the atomic operation (in program
+ \li Release - memory access before the atomic operation (in program
order) may not be re-ordered after the atomic operation.
- \o Ordered - the same Acquire and Release semantics combined.
+ \li Ordered - the same Acquire and Release semantics combined.
\endlist
@@ -753,20 +753,20 @@
\list
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
\endlist
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 52f5a1d699..08952eeaa3 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -66,10 +66,10 @@ QT_BEGIN_NAMESPACE
release():
\list
- \o acquire(\e{n}) tries to acquire \e n resources. If there aren't
+ \li acquire(\e{n}) tries to acquire \e n resources. If there aren't
that many resources available, the call will block until this
is the case.
- \o release(\e{n}) releases \e n resources.
+ \li release(\e{n}) releases \e n resources.
\endlist
There's also a tryAcquire() function that returns immediately if
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index a071463178..64fd8776ce 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -658,11 +658,11 @@ QThread::Priority QThread::priority() const
Blocks the thread until either of these conditions is met:
\list
- \o The thread associated with this QThread object has finished
+ \li The thread associated with this QThread object has finished
execution (i.e. when it returns from \l{run()}). This function
will return true if the thread has finished. It also returns
true if the thread has not been started yet.
- \o \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
+ \li \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
default), then the wait will never timeout (the thread must
return from \l{run()}). This function will return false if the
wait timed out.
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 1dfa3305bc..68db8fe261 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -246,11 +246,11 @@ void QThreadStorageData::finish(void **p)
\list
- \o The QThreadStorage destructor does not delete per-thread data.
+ \li The QThreadStorage destructor does not delete per-thread data.
QThreadStorage only deletes per-thread data when the thread exits
or when setLocalData() is called multiple times.
- \o QThreadStorage can be used to store data for the \c main()
+ \li QThreadStorage can be used to store data for the \c main()
thread. QThreadStorage deletes all data set for the \c main()
thread when QApplication is destroyed, regardless of whether or
not the \c main() thread has actually finished.
diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc
index 7b861f8f7a..8c93bd167d 100644
--- a/src/corelib/thread/qwaitcondition.qdoc
+++ b/src/corelib/thread/qwaitcondition.qdoc
@@ -129,9 +129,9 @@
calling thread will block until either of these conditions is met:
\list
- \o Another thread signals it using wakeOne() or wakeAll(). This
+ \li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \o \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
+ \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
(the default), then the wait will never timeout (the event
must be signalled). This function will return false if the
wait timed out.
@@ -157,9 +157,9 @@
calling thread will block until either of these conditions is met:
\list
- \o Another thread signals it using wakeOne() or wakeAll(). This
+ \li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \o \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
+ \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
(the default), then the wait will never timeout (the event
must be signalled). This function will return false if the
wait timed out.
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index a16ed8b3dc..5a4a278ad0 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -159,14 +159,14 @@
bidirectional iterator, and supports the following operations:
\table
- \row \i \c{i += n} \i advances iterator \c i by \c n positions
- \row \i \c{i -= n} \i moves iterator \c i back by \c n positions
- \row \i \c{i + n} or \c{n + i} \i returns the iterator for the item \c
+ \row \li \c{i += n} \li advances iterator \c i by \c n positions
+ \row \li \c{i -= n} \li moves iterator \c i back by \c n positions
+ \row \li \c{i + n} or \c{n + i} \li returns the iterator for the item \c
n positions ahead of iterator \c i
- \row \i \c{i - n} \i returns the iterator for the item \c n positions behind of iterator \c i
- \row \i \c{i - j} \i returns the number of items between iterators \c i and \c j
- \row \i \c{i[n]} \i same as \c{*(i + n)}
- \row \i \c{i < j} \i returns true if iterator \c j comes after iterator \c i
+ \row \li \c{i - n} \li returns the iterator for the item \c n positions behind of iterator \c i
+ \row \li \c{i - j} \li returns the number of items between iterators \c i and \c j
+ \row \li \c{i[n]} \li same as \c{*(i + n)}
+ \row \li \c{i < j} \li returns true if iterator \c j comes after iterator \c i
\endtable
QList and QVector's non-const iterator types are random access iterators.
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 1d37f578b8..b6719c9536 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -505,7 +505,7 @@ QByteArray qCompress(const uchar* data, int nbytes, int compressionLevel)
from this and any earlier Qt version, back to Qt 3.1 when this
feature was added.
- \bold{Note:} If you want to use this function to uncompress external
+ \b{Note:} If you want to use this function to uncompress external
data that was compressed using zlib, you first need to prepend a four
byte header to the byte array containing the data. The header must
contain the expected length (in bytes) of the uncompressed data,
@@ -3689,12 +3689,12 @@ QByteArray &QByteArray::setNum(qulonglong n, int base)
The format \a f can be any of the following:
\table
- \header \i Format \i Meaning
- \row \i \c e \i format as [-]9.9e[+|-]999
- \row \i \c E \i format as [-]9.9E[+|-]999
- \row \i \c f \i format as [-]9.9
- \row \i \c g \i use \c e or \c f format, whichever is the most concise
- \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
With 'e', 'E', and 'f', \a prec is the number of digits after the
@@ -3818,12 +3818,12 @@ QByteArray QByteArray::number(qulonglong n, int base)
which is \c g by default, and can be any of the following:
\table
- \header \i Format \i Meaning
- \row \i \c e \i format as [-]9.9e[+|-]999
- \row \i \c E \i format as [-]9.9E[+|-]999
- \row \i \c f \i format as [-]9.9
- \row \i \c g \i use \c e or \c f format, whichever is the most concise
- \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
With 'e', 'E', and 'f', \a prec is the number of digits after the
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 31a0fdc5e6..3730a6c580 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -52,9 +52,18 @@
from from stdint.h, but since this header is not available on all platforms
(MSVC 2008, for example), we need to define them ourselves.
*/
+#ifndef _UINT64_T_DECLARED
typedef QT_PREPEND_NAMESPACE(quint64) uint64_t;
+#endif
+
+#ifndef _UINT32_T_DECLARED
typedef QT_PREPEND_NAMESPACE(quint32) uint32_t;
+#endif
+
+#ifndef _UINT8_T_DECLARED
typedef QT_PREPEND_NAMESPACE(quint8) uint8_t;
+#endif
+
typedef QT_PREPEND_NAMESPACE(qint16) int_least16_t;
// Header from rfc6234 with 1 modification:
// sha1.h - commented out '#include <stdint.h>' on line 74
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 70efb5db22..64ad3121d0 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -306,18 +306,18 @@ int QDate::year() const
the following convention:
\list
- \i 1 = "January"
- \i 2 = "February"
- \i 3 = "March"
- \i 4 = "April"
- \i 5 = "May"
- \i 6 = "June"
- \i 7 = "July"
- \i 8 = "August"
- \i 9 = "September"
- \i 10 = "October"
- \i 11 = "November"
- \i 12 = "December"
+ \li 1 = "January"
+ \li 2 = "February"
+ \li 3 = "March"
+ \li 4 = "April"
+ \li 5 = "May"
+ \li 6 = "June"
+ \li 7 = "July"
+ \li 8 = "August"
+ \li 9 = "September"
+ \li 10 = "October"
+ \li 11 = "November"
+ \li 12 = "December"
\endlist
Returns 0 if the date is invalid.
@@ -521,18 +521,18 @@ int QDate::weekNumber(int *yearNumber) const
The months are enumerated using the following convention:
\list
- \i 1 = "Jan"
- \i 2 = "Feb"
- \i 3 = "Mar"
- \i 4 = "Apr"
- \i 5 = "May"
- \i 6 = "Jun"
- \i 7 = "Jul"
- \i 8 = "Aug"
- \i 9 = "Sep"
- \i 10 = "Oct"
- \i 11 = "Nov"
- \i 12 = "Dec"
+ \li 1 = "Jan"
+ \li 2 = "Feb"
+ \li 3 = "Mar"
+ \li 4 = "Apr"
+ \li 5 = "May"
+ \li 6 = "Jun"
+ \li 7 = "Jul"
+ \li 8 = "Aug"
+ \li 9 = "Sep"
+ \li 10 = "Oct"
+ \li 11 = "Nov"
+ \li 12 = "Dec"
\endlist
The month names will be localized according to the system's locale
@@ -568,18 +568,18 @@ QString QDate::shortMonthName(int month, QDate::MonthNameType type)
The months are enumerated using the following convention:
\list
- \i 1 = "January"
- \i 2 = "February"
- \i 3 = "March"
- \i 4 = "April"
- \i 5 = "May"
- \i 6 = "June"
- \i 7 = "July"
- \i 8 = "August"
- \i 9 = "September"
- \i 10 = "October"
- \i 11 = "November"
- \i 12 = "December"
+ \li 1 = "January"
+ \li 2 = "February"
+ \li 3 = "March"
+ \li 4 = "April"
+ \li 5 = "May"
+ \li 6 = "June"
+ \li 7 = "July"
+ \li 8 = "August"
+ \li 9 = "September"
+ \li 10 = "October"
+ \li 11 = "November"
+ \li 12 = "December"
\endlist
The month names will be localized according to the system's locale
@@ -615,13 +615,13 @@ QString QDate::longMonthName(int month, MonthNameType type)
The days are enumerated using the following convention:
\list
- \i 1 = "Mon"
- \i 2 = "Tue"
- \i 3 = "Wed"
- \i 4 = "Thu"
- \i 5 = "Fri"
- \i 6 = "Sat"
- \i 7 = "Sun"
+ \li 1 = "Mon"
+ \li 2 = "Tue"
+ \li 3 = "Wed"
+ \li 4 = "Thu"
+ \li 5 = "Fri"
+ \li 6 = "Sat"
+ \li 7 = "Sun"
\endlist
The day names will be localized according to the system's locale
@@ -657,13 +657,13 @@ QString QDate::shortDayName(int weekday, MonthNameType type)
The days are enumerated using the following convention:
\list
- \i 1 = "Monday"
- \i 2 = "Tuesday"
- \i 3 = "Wednesday"
- \i 4 = "Thursday"
- \i 5 = "Friday"
- \i 6 = "Saturday"
- \i 7 = "Sunday"
+ \li 1 = "Monday"
+ \li 2 = "Tuesday"
+ \li 3 = "Wednesday"
+ \li 4 = "Thursday"
+ \li 5 = "Friday"
+ \li 6 = "Saturday"
+ \li 7 = "Sunday"
\endlist
The day names will be localized according to the system's locale
@@ -781,25 +781,25 @@ QString QDate::toString(Qt::DateFormat f) const
These expressions may be used:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1 to 12)
- \row \i MM \i the month as number with a leading zero (01 to 12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1 to 12)
+ \row \li MM \li the month as number with a leading zero (01 to 12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00 to 99)
- \row \i yyyy \i the year as four digit number. If the year is negative,
+ \row \li yy \li the year as two digit number (00 to 99)
+ \row \li yyyy \li the year as four digit number. If the year is negative,
a minus sign is prepended in addition.
\endtable
@@ -812,10 +812,10 @@ QString QDate::toString(Qt::DateFormat f) const
1969):
\table
- \header \o Format \o Result
- \row \o dd.MM.yyyy \o 20.07.1969
- \row \o ddd MMMM d yy \o Sun July 20 69
- \row \o 'The day is' dddd \o The day is Sunday
+ \header \li Format \li Result
+ \row \li dd.MM.yyyy \li 20.07.1969
+ \row \li ddd MMMM d yy \li Sun July 20 69
+ \row \li 'The day is' dddd \li The day is Sunday
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -1191,25 +1191,25 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the format:
\table
- \header \i Expression \i Output
- \row \i d \i The day as a number without a leading zero (1 to 31)
- \row \i dd \i The day as a number with a leading zero (01 to 31)
- \row \i ddd
- \i The abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li The day as a number without a leading zero (1 to 31)
+ \row \li dd \li The day as a number with a leading zero (01 to 31)
+ \row \li ddd
+ \li The abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i The long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li The long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i The month as a number without a leading zero (1 to 12)
- \row \i MM \i The month as a number with a leading zero (01 to 12)
- \row \i MMM
- \i The abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li The month as a number without a leading zero (1 to 12)
+ \row \li MM \li The month as a number with a leading zero (01 to 12)
+ \row \li MMM
+ \li The abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i The long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li The long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i The year as two digit number (00 to 99)
- \row \i yyyy \i The year as four digit number. If the year is negative,
+ \row \li yy \li The year as two digit number (00 to 99)
+ \row \li yyyy \li The year as four digit number. If the year is negative,
a minus sign is prepended in addition.
\endtable
@@ -1233,10 +1233,10 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
defaults are used:
\table
- \header \i Field \i Default value
- \row \i Year \i 1900
- \row \i Month \i 1
- \row \i Day \i 1
+ \header \li Field \li Default value
+ \row \li Year \li 1900
+ \row \li Month \li 1
+ \row \li Day \li 1
\endtable
The following examples demonstrate the default values:
@@ -1543,26 +1543,26 @@ QString QTime::toString(Qt::DateFormat format) const
These expressions may be used:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i H
- \i the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \i HH
- \i the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP or A
- \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
- \row \i ap or a
- \i use am/pm display. \e ap will be replaced by either "am" or "pm".
- \row \i t \i the timezone (for example "CEST")
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li H
+ \li the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \li HH
+ \li the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP or A
+ \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \li ap or a
+ \li use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \row \li t \li the timezone (for example "CEST")
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -1573,10 +1573,10 @@ QString QTime::toString(Qt::DateFormat format) const
Example format strings (assuming that the QTime is 14:13:09.042)
\table
- \header \i Format \i Result
- \row \i hh:mm:ss.zzz \i 14:13:09.042
- \row \i h:m:s ap \i 2:13:9 pm
- \row \i H:m:s a \i 14:13:9 pm
+ \header \li Format \li Result
+ \row \li hh:mm:ss.zzz \li 14:13:09.042
+ \row \li h:m:s ap \li 2:13:9 pm
+ \row \li H:m:s a \li 14:13:9 pm
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -1824,21 +1824,21 @@ QTime QTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the format:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP
- \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \i ap
- \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP
+ \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \li ap
+ \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
\endtable
All other input characters will be treated as text. Any sequence
@@ -2515,45 +2515,45 @@ QString QDateTime::toString(Qt::DateFormat f) const
These expressions may be used for the date:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1-12)
- \row \i MM \i the month as number with a leading zero (01-12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1-12)
+ \row \li MM \li the month as number with a leading zero (01-12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00-99)
- \row \i yyyy \i the year as four digit number
+ \row \li yy \li the year as two digit number (00-99)
+ \row \li yyyy \li the year as four digit number
\endtable
These expressions may be used for the time:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP
- \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
- \row \i ap
- \i use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP
+ \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \li ap
+ \li use am/pm display. \e ap will be replaced by either "am" or "pm".
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -2565,11 +2565,11 @@ QString QDateTime::toString(Qt::DateFormat f) const
14:13:09):
\table
- \header \i Format \i Result
- \row \i dd.MM.yyyy \i 21.05.2001
- \row \i ddd MMMM d yy \i Tue May 21 01
- \row \i hh:mm:ss.zzz \i 14:13:09.042
- \row \i h:m:s ap \i 2:13:9 pm
+ \header \li Format \li Result
+ \row \li dd.MM.yyyy \li 21.05.2001
+ \row \li ddd MMMM d yy \li Tue May 21 01
+ \row \li hh:mm:ss.zzz \li 14:13:09.042
+ \row \li h:m:s ap \li 2:13:9 pm
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -3367,25 +3367,25 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the date part of the format string:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1-12)
- \row \i MM \i the month as number with a leading zero (01-12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1-12)
+ \row \li MM \li the month as number with a leading zero (01-12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00-99)
- \row \i yyyy \i the year as four digit number
+ \row \li yy \li the year as two digit number (00-99)
+ \row \li yyyy \li the year as four digit number
\endtable
\note Unlike the other version of this function, day and month names must
@@ -3395,25 +3395,25 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the time part of the format string:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i H
- \i the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \i HH
- \i the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP or A
- \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \i ap or a
- \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li H
+ \li the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \li HH
+ \li the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP or A
+ \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \li ap or a
+ \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
\endtable
All other input characters will be treated as text. Any sequence
@@ -3437,13 +3437,13 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
defaults are used:
\table
- \header \i Field \i Default value
- \row \i Year \i 1900
- \row \i Month \i 1 (January)
- \row \i Day \i 1
- \row \i Hour \i 0
- \row \i Minute \i 0
- \row \i Second \i 0
+ \header \li Field \li Default value
+ \row \li Year \li 1900
+ \row \li Month \li 1 (January)
+ \row \li Day \li 1
+ \row \li Hour \li 0
+ \row \li Minute \li 0
+ \row \li Second \li 0
\endtable
For example:
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 36497c59ff..d5703e8b2a 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -547,11 +547,11 @@ void QHashData::checkSanity()
differences are:
\list
- \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
- \i When iterating over a QMap, the items are always sorted by
+ \li When iterating over a QMap, the items are always sorted by
key. With QHash, the items are arbitrarily ordered.
- \i The key type of a QMap must provide operator<(). The key
+ \li The key type of a QMap must provide operator<(). The key
type of a QHash must provide operator==() and a global
hash function called qHash() (see the related non-member
functions).
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index 78f1c44263..39ec0ed97c 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -61,8 +61,8 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qline-point.png
- \o \inlineimage qline-coordinates.png
+ \li \inlineimage qline-point.png
+ \li \inlineimage qline-coordinates.png
\endtable
The positions of the line's start and end points can be retrieved
@@ -322,8 +322,8 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
\table
\row
- \o \inlineimage qline-point.png
- \o \inlineimage qline-coordinates.png
+ \li \inlineimage qline-point.png
+ \li \inlineimage qline-coordinates.png
\endtable
The positions of the line's start and end points can be retrieved
@@ -360,11 +360,11 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
\table
\row
- \o \inlineimage qlinef-unbounded.png
- \o \inlineimage qlinef-bounded.png
+ \li \inlineimage qlinef-unbounded.png
+ \li \inlineimage qlinef-bounded.png
\row
- \o QLineF::UnboundedIntersection
- \o QLineF::BoundedIntersection
+ \li QLineF::UnboundedIntersection
+ \li QLineF::BoundedIntersection
\endtable
\value NoIntersection Indicates that the lines do not intersect;
@@ -795,8 +795,8 @@ qreal QLineF::angleTo(const QLineF &l) const
\table
\row
- \o \inlineimage qlinef-angle-identicaldirection.png
- \o \inlineimage qlinef-angle-oppositedirection.png
+ \li \inlineimage qlinef-angle-identicaldirection.png
+ \li \inlineimage qlinef-angle-oppositedirection.png
\endtable
When the lines are parallel, this function returns 0 if they have
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index e2efaa3639..b31ef3e5e9 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -65,16 +65,16 @@ const QLinkedListData QLinkedListData::shared_null = {
functionality. Here's an overview:
\list
- \i For most purposes, QList is the right class to use. Its
+ \li For most purposes, QList is the right class to use. Its
index-based API is more convenient than QLinkedList's
iterator-based API, and it is usually faster than
QVector because of the way it stores its items in
memory (see \l{Algorithmic Complexity} for details).
It also expands to less code in your executable.
- \i If you need a real linked list, with guarantees of \l{constant
+ \li If you need a real linked list, with guarantees of \l{constant
time} insertions in the middle of the list and iterators to
items rather than indexes, use QLinkedList.
- \i If you want the items to occupy adjacent memory positions,
+ \li If you want the items to occupy adjacent memory positions,
use QVector.
\endlist
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index b8c938e216..263045a25d 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -340,15 +340,15 @@ void **QListData::erase(void **xi)
functionality. Here's an overview:
\list
- \i For most purposes, QList is the right class to use. Its
+ \li For most purposes, QList is the right class to use. Its
index-based API is more convenient than QLinkedList's
iterator-based API, and it is usually faster than
QVector because of the way it stores its items in
memory. It also expands to less code in your executable.
- \i If you need a real linked list, with guarantees of \l{constant
+ \li If you need a real linked list, with guarantees of \l{constant
time} insertions in the middle of the list and iterators to
items rather than indexes, use QLinkedList.
- \i If you want the items to occupy adjacent memory positions,
+ \li If you want the items to occupy adjacent memory positions,
use QVector.
\endlist
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 31f776dc2e..086ca7bd38 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -621,10 +621,10 @@ static quint16 localePrivateIndex(const QLocalePrivate *p)
"language[_script][_country][.codeset][@modifier]" or "C", where:
\list
- \i language is a lowercase, two-letter, ISO 639 language code,
- \i script is a titlecase, four-letter, ISO 15924 script code,
- \i country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations),
- \i and codeset and modifier are ignored.
+ \li language is a lowercase, two-letter, ISO 639 language code,
+ \li script is a titlecase, four-letter, ISO 15924 script code,
+ \li country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations),
+ \li and codeset and modifier are ignored.
\endlist
The separator can be either underscore or a minus sign.
@@ -671,11 +671,11 @@ QLocale::QLocale()
country.
\list
- \i If the language/country pair is found in the database, it is used.
- \i If the language is found but the country is not, or if the country
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
is \c AnyCountry, the language is used with the most
appropriate available country (for example, Germany for German),
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
@@ -707,14 +707,14 @@ QLocale::QLocale(Language language, Country country)
\a country.
\list
- \i If the language/script/country is found in the database, it is used.
- \i If both \a script is AnyScript and \a country is AnyCountry, the
+ \li If the language/script/country is found in the database, it is used.
+ \li If both \a script is AnyScript and \a country is AnyCountry, the
language is used with the most appropriate available script and country
(for example, Germany for German),
- \i If either \a script is AnyScript or \a country is AnyCountry, the
+ \li If either \a script is AnyScript or \a country is AnyCountry, the
language is used with the first locale that matches the given \a script
and \a country.
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 3a386c17d6..8e90d7d94e 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -51,12 +51,12 @@
following effects:
\list
- \i If a QLocale object is constructed with the default constructor,
+ \li If a QLocale object is constructed with the default constructor,
it will use the default locale's settings.
- \i QString::toInt(), QString::toDouble(), etc., interpret the
+ \li QString::toInt(), QString::toDouble(), etc., interpret the
string according to the default locale. If this fails, it
falls back on the "C" locale.
- \i QString::arg() uses the default locale to format a number when
+ \li QString::arg() uses the default locale to format a number when
its position specifier in the format string contains an 'L',
e.g. "%L1".
\endlist
@@ -69,11 +69,11 @@
of three things can happen:
\list
- \i If the language/country pair is found in the database, it is used.
- \i If the language is found but the country is not, or if the country
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
is \c AnyCountry, the language is used with the most
appropriate available country (for example, Germany for German),
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 31a29d7fe1..2d6b8047a6 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -601,7 +601,7 @@ QT_END_INCLUDE_NAMESPACE
#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
#endif
-static inline ULong _getWord0(const NEEDS_VOLATILE double x)
+static inline ULong getWord0(const NEEDS_VOLATILE double x)
{
const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -611,7 +611,7 @@ static inline ULong _getWord0(const NEEDS_VOLATILE double x)
}
}
-static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
+static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
{
NEEDS_VOLATILE uchar *ptr = reinterpret_cast<NEEDS_VOLATILE uchar *>(x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -627,7 +627,7 @@ static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
}
}
-static inline ULong _getWord1(const NEEDS_VOLATILE double x)
+static inline ULong getWord1(const NEEDS_VOLATILE double x)
{
const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -636,7 +636,7 @@ static inline ULong _getWord1(const NEEDS_VOLATILE double x)
return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
}
}
-static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
+static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
{
NEEDS_VOLATILE uchar *ptr = reinterpret_cast<uchar NEEDS_VOLATILE *>(x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -652,42 +652,6 @@ static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
}
}
-static inline ULong getWord0(const NEEDS_VOLATILE double x)
-{
-#ifdef QT_ARMFPA
- return _getWord1(x);
-#else
- return _getWord0(x);
-#endif
-}
-
-static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
-{
-#ifdef QT_ARMFPA
- _setWord1(x, l);
-#else
- _setWord0(x, l);
-#endif
-}
-
-static inline ULong getWord1(const NEEDS_VOLATILE double x)
-{
-#ifdef QT_ARMFPA
- return _getWord0(x);
-#else
- return _getWord1(x);
-#endif
-}
-
-static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
-{
-#ifdef QT_ARMFPA
- _setWord0(x, l);
-#else
- _setWord1(x, l);
-#endif
-}
-
static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
{
diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h
index 2dc5c03a20..d920d41cb3 100644
--- a/src/corelib/tools/qlocale_tools_p.h
+++ b/src/corelib/tools/qlocale_tools_p.h
@@ -97,15 +97,11 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
inline bool isZero(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return !(ch[3] & 0x7F || ch[2] || ch[1] || ch[0] || ch[7] || ch[6] || ch[5] || ch[4]);
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]);
} else {
return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]);
}
-#endif
}
// Removes thousand-group separators in "C" locale.
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 37d705b3e0..103d074941 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -232,11 +232,11 @@ void QMapData::dump()
differences are:
\list
- \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
- \i When iterating over a QHash, the items are arbitrarily ordered.
+ \li When iterating over a QHash, the items are arbitrarily ordered.
With QMap, the items are always sorted by key.
- \i The key type of a QHash must provide operator==() and a global
+ \li The key type of a QHash must provide operator==() and a global
qHash(Key) function. The key type of a QMap must provide
operator<() specifying a total order.
\endlist
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 29eb58bd22..4dc28f2d26 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -55,11 +55,9 @@ struct QPair
typedef T1 first_type;
typedef T2 second_type;
- QPair() : first(T1()), second(T2()) {}
+ QPair() : first(), second() {}
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
-
- QPair<T1, T2> &operator=(const QPair<T1, T2> &other)
- { first = other.first; second = other.second; return *this; }
+ // compiler-generated copy/move ctor/assignment operators are fine!
T1 first;
T2 second;
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index 7ff883a99a..aeab97803d 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -99,11 +99,11 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qrect-intersect.png
- \o \inlineimage qrect-unite.png
+ \li \inlineimage qrect-intersect.png
+ \li \inlineimage qrect-unite.png
\row
- \o intersected()
- \o united()
+ \li intersected()
+ \li united()
\endtable
The isEmpty() function returns true if left() > right() or top() >
@@ -139,17 +139,17 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrect-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrect-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrect-diagram-two.png
- \o \inlineimage qrect-diagram-three.png
+ \li \inlineimage qrect-diagram-two.png
+ \li \inlineimage qrect-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
\section1 Coordinates
@@ -1278,11 +1278,11 @@ QDebug operator<<(QDebug dbg, const QRect &r) {
\table
\row
- \o \inlineimage qrect-intersect.png
- \o \inlineimage qrect-unite.png
+ \li \inlineimage qrect-intersect.png
+ \li \inlineimage qrect-unite.png
\row
- \o intersected()
- \o united()
+ \li intersected()
+ \li united()
\endtable
The isEmpty() function returns true if the rectangle's width or
@@ -1318,17 +1318,17 @@ QDebug operator<<(QDebug dbg, const QRect &r) {
\table
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrectf-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrectf-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrectf-diagram-two.png
- \o \inlineimage qrectf-diagram-three.png
+ \li \inlineimage qrectf-diagram-two.png
+ \li \inlineimage qrectf-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
\section1 Coordinates
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index d7bcd0edbc..29b3424315 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -90,21 +90,21 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
substrings in a text. This is useful in many contexts, e.g.,
\table
- \row \i Validation
- \i A regexp can test whether a substring meets some criteria,
+ \row \li Validation
+ \li A regexp can test whether a substring meets some criteria,
e.g. is an integer or contains no whitespace.
- \row \i Searching
- \i A regexp provides more powerful pattern matching than
+ \row \li Searching
+ \li A regexp provides more powerful pattern matching than
simple substring matching, e.g., match one of the words
\e{mail}, \e{letter} or \e{correspondence}, but none of the
words \e{email}, \e{mailman}, \e{mailer}, \e{letterbox}, etc.
- \row \i Search and Replace
- \i A regexp can replace all occurrences of a substring with a
+ \row \li Search and Replace
+ \li A regexp can replace all occurrences of a substring with a
different substring, e.g., replace all occurrences of \e{&}
with \e{\&amp;} except where the \e{&} is already followed by
an \e{amp;}.
- \row \i String Splitting
- \i A regexp can be used to identify where a string should be
+ \row \li String Splitting
+ \li A regexp can be used to identify where a string should be
split apart, e.g. splitting tab-delimited strings.
\endtable
@@ -127,18 +127,18 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Introduction
Regexps are built up from expressions, quantifiers, and
- assertions. The simplest expression is a character, e.g. \bold{x}
- or \bold{5}. An expression can also be a set of characters
- enclosed in square brackets. \bold{[ABCD]} will match an \bold{A}
- or a \bold{B} or a \bold{C} or a \bold{D}. We can write this same
- expression as \bold{[A-D]}, and an experession to match any
+ assertions. The simplest expression is a character, e.g. \b{x}
+ or \b{5}. An expression can also be a set of characters
+ enclosed in square brackets. \b{[ABCD]} will match an \b{A}
+ or a \b{B} or a \b{C} or a \b{D}. We can write this same
+ expression as \b{[A-D]}, and an experession to match any
captital letter in the English alphabet is written as
- \bold{[A-Z]}.
+ \b{[A-Z]}.
A quantifier specifies the number of occurrences of an expression
- that must be matched. \bold{x{1,1}} means match one and only one
- \bold{x}. \bold{x{1,5}} means match a sequence of \bold{x}
- characters that contains at least one \bold{x} but no more than
+ that must be matched. \b{x{1,1}} means match one and only one
+ \b{x}. \b{x{1,5}} means match a sequence of \b{x}
+ characters that contains at least one \b{x} but no more than
five.
Note that in general regexps cannot be used to check for balanced
@@ -156,35 +156,35 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Suppose we want a regexp to match integers in the range 0 to 99.
At least one digit is required, so we start with the expression
- \bold{[0-9]{1,1}}, which matches a single digit exactly once. This
+ \b{[0-9]{1,1}}, which matches a single digit exactly once. This
regexp matches integers in the range 0 to 9. To match integers up
to 99, increase the maximum number of occurrences to 2, so the
- regexp becomes \bold{[0-9]{1,2}}. This regexp satisfies the
+ regexp becomes \b{[0-9]{1,2}}. This regexp satisfies the
original requirement to match integers from 0 to 99, but it will
also match integers that occur in the middle of strings. If we
want the matched integer to be the whole string, we must use the
- anchor assertions, \bold{^} (caret) and \bold{$} (dollar). When
- \bold{^} is the first character in a regexp, it means the regexp
- must match from the beginning of the string. When \bold{$} is the
+ anchor assertions, \b{^} (caret) and \b{$} (dollar). When
+ \b{^} is the first character in a regexp, it means the regexp
+ must match from the beginning of the string. When \b{$} is the
last character of the regexp, it means the regexp must match to
- the end of the string. The regexp becomes \bold{^[0-9]{1,2}$}.
- Note that assertions, e.g. \bold{^} and \bold{$}, do not match
+ the end of the string. The regexp becomes \b{^[0-9]{1,2}$}.
+ Note that assertions, e.g. \b{^} and \b{$}, do not match
characters but locations in the string.
If you have seen regexps described elsewhere, they may have looked
different from the ones shown here. This is because some sets of
characters and some quantifiers are so common that they have been
- given special symbols to represent them. \bold{[0-9]} can be
- replaced with the symbol \bold{\\d}. The quantifier to match
- exactly one occurrence, \bold{{1,1}}, can be replaced with the
- expression itself, i.e. \bold{x{1,1}} is the same as \bold{x}. So
- our 0 to 99 matcher could be written as \bold{^\\d{1,2}$}. It can
- also be written \bold{^\\d\\d{0,1}$}, i.e. \e{From the start of
+ given special symbols to represent them. \b{[0-9]} can be
+ replaced with the symbol \b{\\d}. The quantifier to match
+ exactly one occurrence, \b{{1,1}}, can be replaced with the
+ expression itself, i.e. \b{x{1,1}} is the same as \b{x}. So
+ our 0 to 99 matcher could be written as \b{^\\d{1,2}$}. It can
+ also be written \b{^\\d\\d{0,1}$}, i.e. \e{From the start of
the string, match a digit, followed immediately by 0 or 1 digits}.
- In practice, it would be written as \bold{^\\d\\d?$}. The \bold{?}
- is shorthand for the quantifier \bold{{0,1}}, i.e. 0 or 1
- occurrences. \bold{?} makes an expression optional. The regexp
- \bold{^\\d\\d?$} means \e{From the beginning of the string, match
+ In practice, it would be written as \b{^\\d\\d?$}. The \b{?}
+ is shorthand for the quantifier \b{{0,1}}, i.e. 0 or 1
+ occurrences. \b{?} makes an expression optional. The regexp
+ \b{^\\d\\d?$} means \e{From the beginning of the string, match
one digit, followed immediately by 0 or 1 more digit, followed
immediately by end of string}.
@@ -192,45 +192,45 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
'letter' \e or 'correspondence' but does not match words that
contain these words, e.g., 'email', 'mailman', 'mailer', and
'letterbox', start with a regexp that matches 'mail'. Expressed
- fully, the regexp is \bold{m{1,1}a{1,1}i{1,1}l{1,1}}, but because
+ fully, the regexp is \b{m{1,1}a{1,1}i{1,1}l{1,1}}, but because
a character expression is automatically quantified by
- \bold{{1,1}}, we can simplify the regexp to \bold{mail}, i.e., an
+ \b{{1,1}}, we can simplify the regexp to \b{mail}, i.e., an
'm' followed by an 'a' followed by an 'i' followed by an 'l'. Now
- we can use the vertical bar \bold{|}, which means \bold{or}, to
+ we can use the vertical bar \b{|}, which means \b{or}, to
include the other two words, so our regexp for matching any of the
- three words becomes \bold{mail|letter|correspondence}. Match
- 'mail' \bold{or} 'letter' \bold{or} 'correspondence'. While this
+ three words becomes \b{mail|letter|correspondence}. Match
+ 'mail' \b{or} 'letter' \b{or} 'correspondence'. While this
regexp will match one of the three words we want to match, it will
also match words we don't want to match, e.g., 'email'. To
prevent the regexp from matching unwanted words, we must tell it
to begin and end the match at word boundaries. First we enclose
- our regexp in parentheses, \bold{(mail|letter|correspondence)}.
+ our regexp in parentheses, \b{(mail|letter|correspondence)}.
Parentheses group expressions together, and they identify a part
of the regexp that we wish to \l{capturing text}{capture}.
Enclosing the expression in parentheses allows us to use it as a
component in more complex regexps. It also allows us to examine
which of the three words was actually matched. To force the match
to begin and end on word boundaries, we enclose the regexp in
- \bold{\\b} \e{word boundary} assertions:
- \bold{\\b(mail|letter|correspondence)\\b}. Now the regexp means:
+ \b{\\b} \e{word boundary} assertions:
+ \b{\\b(mail|letter|correspondence)\\b}. Now the regexp means:
\e{Match a word boundary, followed by the regexp in parentheses,
- followed by a word boundary}. The \bold{\\b} assertion matches a
+ followed by a word boundary}. The \b{\\b} assertion matches a
\e position in the regexp, not a \e character. A word boundary is
any non-word character, e.g., a space, newline, or the beginning
or ending of a string.
If we want to replace ampersand characters with the HTML entity
- \bold{\&amp;}, the regexp to match is simply \bold{\&}. But this
+ \b{\&amp;}, the regexp to match is simply \b{\&}. But this
regexp will also match ampersands that have already been converted
to HTML entities. We want to replace only ampersands that are not
- already followed by \bold{amp;}. For this, we need the negative
- lookahead assertion, \bold{(?!}__\bold{)}. The regexp can then be
- written as \bold{\&(?!amp;)}, i.e. \e{Match an ampersand that is}
- \bold{not} \e{followed by} \bold{amp;}.
+ already followed by \b{amp;}. For this, we need the negative
+ lookahead assertion, \b{(?!}__\b{)}. The regexp can then be
+ written as \b{\&(?!amp;)}, i.e. \e{Match an ampersand that is}
+ \b{not} \e{followed by} \b{amp;}.
If we want to count all the occurrences of 'Eric' and 'Eirik' in a
- string, two valid solutions are \bold{\\b(Eric|Eirik)\\b} and
- \bold{\\bEi?ri[ck]\\b}. The word boundary assertion '\\b' is
+ string, two valid solutions are \b{\\b(Eric|Eirik)\\b} and
+ \b{\\bEi?ri[ck]\\b}. The word boundary assertion '\\b' is
required to avoid matching words that contain either name,
e.g. 'Ericsson'. Note that the second regexp matches more
spellings than we want: 'Eric', 'Erik', 'Eiric' and 'Eirik'.
@@ -242,52 +242,52 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Characters and Abbreviations for Sets of Characters
\table
- \header \i Element \i Meaning
- \row \i \bold{c}
- \i A character represents itself unless it has a special
- regexp meaning. e.g. \bold{c} matches the character \e c.
- \row \i \bold{\\c}
- \i A character that follows a backslash matches the character
+ \header \li Element \li Meaning
+ \row \li \b{c}
+ \li A character represents itself unless it has a special
+ regexp meaning. e.g. \b{c} matches the character \e c.
+ \row \li \b{\\c}
+ \li A character that follows a backslash matches the character
itself, except as specified below. e.g., To match a literal
- caret at the beginning of a string, write \bold{\\^}.
- \row \i \bold{\\a}
- \i Matches the ASCII bell (BEL, 0x07).
- \row \i \bold{\\f}
- \i Matches the ASCII form feed (FF, 0x0C).
- \row \i \bold{\\n}
- \i Matches the ASCII line feed (LF, 0x0A, Unix newline).
- \row \i \bold{\\r}
- \i Matches the ASCII carriage return (CR, 0x0D).
- \row \i \bold{\\t}
- \i Matches the ASCII horizontal tab (HT, 0x09).
- \row \i \bold{\\v}
- \i Matches the ASCII vertical tab (VT, 0x0B).
- \row \i \bold{\\x\e{hhhh}}
- \i Matches the Unicode character corresponding to the
+ caret at the beginning of a string, write \b{\\^}.
+ \row \li \b{\\a}
+ \li Matches the ASCII bell (BEL, 0x07).
+ \row \li \b{\\f}
+ \li Matches the ASCII form feed (FF, 0x0C).
+ \row \li \b{\\n}
+ \li Matches the ASCII line feed (LF, 0x0A, Unix newline).
+ \row \li \b{\\r}
+ \li Matches the ASCII carriage return (CR, 0x0D).
+ \row \li \b{\\t}
+ \li Matches the ASCII horizontal tab (HT, 0x09).
+ \row \li \b{\\v}
+ \li Matches the ASCII vertical tab (VT, 0x0B).
+ \row \li \b{\\x\e{hhhh}}
+ \li Matches the Unicode character corresponding to the
hexadecimal number \e{hhhh} (between 0x0000 and 0xFFFF).
- \row \i \bold{\\0\e{ooo}} (i.e., \\zero \e{ooo})
- \i matches the ASCII/Latin1 character for the octal number
+ \row \li \b{\\0\e{ooo}} (i.e., \\zero \e{ooo})
+ \li matches the ASCII/Latin1 character for the octal number
\e{ooo} (between 0 and 0377).
- \row \i \bold{. (dot)}
- \i Matches any character (including newline).
- \row \i \bold{\\d}
- \i Matches a digit (QChar::isDigit()).
- \row \i \bold{\\D}
- \i Matches a non-digit.
- \row \i \bold{\\s}
- \i Matches a whitespace character (QChar::isSpace()).
- \row \i \bold{\\S}
- \i Matches a non-whitespace character.
- \row \i \bold{\\w}
- \i Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
- \row \i \bold{\\W}
- \i Matches a non-word character.
- \row \i \bold{\\\e{n}}
- \i The \e{n}-th \l backreference, e.g. \\1, \\2, etc.
+ \row \li \b{. (dot)}
+ \li Matches any character (including newline).
+ \row \li \b{\\d}
+ \li Matches a digit (QChar::isDigit()).
+ \row \li \b{\\D}
+ \li Matches a non-digit.
+ \row \li \b{\\s}
+ \li Matches a whitespace character (QChar::isSpace()).
+ \row \li \b{\\S}
+ \li Matches a non-whitespace character.
+ \row \li \b{\\w}
+ \li Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
+ \row \li \b{\\W}
+ \li Matches a non-word character.
+ \row \li \b{\\\e{n}}
+ \li The \e{n}-th \l backreference, e.g. \\1, \\2, etc.
\endtable
- \bold{Note:} The C++ compiler transforms backslashes in strings.
- To include a \bold{\\} in a regexp, enter it twice, i.e. \c{\\}.
+ \b{Note:} The C++ compiler transforms backslashes in strings.
+ To include a \b{\\} in a regexp, enter it twice, i.e. \c{\\}.
To match the backslash character itself, enter it four times, i.e.
\c{\\\\}.
@@ -301,24 +301,24 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
characters do not have special meanings in square brackets.
\table
- \row \i \bold{^}
+ \row \li \b{^}
- \i The caret negates the character set if it occurs as the
+ \li The caret negates the character set if it occurs as the
first character (i.e. immediately after the opening square
- bracket). \bold{[abc]} matches 'a' or 'b' or 'c', but
- \bold{[^abc]} matches anything \e but 'a' or 'b' or 'c'.
+ bracket). \b{[abc]} matches 'a' or 'b' or 'c', but
+ \b{[^abc]} matches anything \e but 'a' or 'b' or 'c'.
- \row \i \bold{-}
+ \row \li \b{-}
- \i The dash indicates a range of characters. \bold{[W-Z]}
+ \li The dash indicates a range of characters. \b{[W-Z]}
matches 'W' or 'X' or 'Y' or 'Z'.
\endtable
Using the predefined character set abbreviations is more portable
than using character ranges across platforms and languages. For
- example, \bold{[0-9]} matches a digit in Western alphabets but
- \bold{\\d} matches a digit in \e any alphabet.
+ example, \b{[0-9]} matches a digit in Western alphabets but
+ \b{\\d} matches a digit in \e any alphabet.
Note: In other regexp documentation, sets of characters are often
called "character classes".
@@ -327,64 +327,64 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Quantifiers
By default, an expression is automatically quantified by
- \bold{{1,1}}, i.e. it should occur exactly once. In the following
- list, \bold{\e {E}} stands for expression. An expression is a
+ \b{{1,1}}, i.e. it should occur exactly once. In the following
+ list, \b{\e {E}} stands for expression. An expression is a
character, or an abbreviation for a set of characters, or a set of
characters in square brackets, or an expression in parentheses.
\table
- \row \i \bold{\e {E}?}
+ \row \li \b{\e {E}?}
- \i Matches zero or one occurrences of \e E. This quantifier
+ \li Matches zero or one occurrences of \e E. This quantifier
means \e{The previous expression is optional}, because it
- will match whether or not the expression is found. \bold{\e
- {E}?} is the same as \bold{\e {E}{0,1}}. e.g., \bold{dents?}
+ will match whether or not the expression is found. \b{\e
+ {E}?} is the same as \b{\e {E}{0,1}}. e.g., \b{dents?}
matches 'dent' or 'dents'.
- \row \i \bold{\e {E}+}
+ \row \li \b{\e {E}+}
- \i Matches one or more occurrences of \e E. \bold{\e {E}+} is
- the same as \bold{\e {E}{1,}}. e.g., \bold{0+} matches '0',
+ \li Matches one or more occurrences of \e E. \b{\e {E}+} is
+ the same as \b{\e {E}{1,}}. e.g., \b{0+} matches '0',
'00', '000', etc.
- \row \i \bold{\e {E}*}
+ \row \li \b{\e {E}*}
- \i Matches zero or more occurrences of \e E. It is the same
- as \bold{\e {E}{0,}}. The \bold{*} quantifier is often used
- in error where \bold{+} should be used. For example, if
- \bold{\\s*$} is used in an expression to match strings that
+ \li Matches zero or more occurrences of \e E. It is the same
+ as \b{\e {E}{0,}}. The \b{*} quantifier is often used
+ in error where \b{+} should be used. For example, if
+ \b{\\s*$} is used in an expression to match strings that
end in whitespace, it will match every string because
- \bold{\\s*$} means \e{Match zero or more whitespaces followed
+ \b{\\s*$} means \e{Match zero or more whitespaces followed
by end of string}. The correct regexp to match strings that
have at least one trailing whitespace character is
- \bold{\\s+$}.
+ \b{\\s+$}.
- \row \i \bold{\e {E}{n}}
+ \row \li \b{\e {E}{n}}
- \i Matches exactly \e n occurrences of \e E. \bold{\e {E}{n}}
+ \li Matches exactly \e n occurrences of \e E. \b{\e {E}{n}}
is the same as repeating \e E \e n times. For example,
- \bold{x{5}} is the same as \bold{xxxxx}. It is also the same
- as \bold{\e {E}{n,n}}, e.g. \bold{x{5,5}}.
+ \b{x{5}} is the same as \b{xxxxx}. It is also the same
+ as \b{\e {E}{n,n}}, e.g. \b{x{5,5}}.
- \row \i \bold{\e {E}{n,}}
- \i Matches at least \e n occurrences of \e E.
+ \row \li \b{\e {E}{n,}}
+ \li Matches at least \e n occurrences of \e E.
- \row \i \bold{\e {E}{,m}}
- \i Matches at most \e m occurrences of \e E. \bold{\e {E}{,m}}
- is the same as \bold{\e {E}{0,m}}.
+ \row \li \b{\e {E}{,m}}
+ \li Matches at most \e m occurrences of \e E. \b{\e {E}{,m}}
+ is the same as \b{\e {E}{0,m}}.
- \row \i \bold{\e {E}{n,m}}
- \i Matches at least \e n and at most \e m occurrences of \e E.
+ \row \li \b{\e {E}{n,m}}
+ \li Matches at least \e n and at most \e m occurrences of \e E.
\endtable
To apply a quantifier to more than just the preceding character,
use parentheses to group characters together in an expression. For
- example, \bold{tag+} matches a 't' followed by an 'a' followed by
- at least one 'g', whereas \bold{(tag)+} matches at least one
+ example, \b{tag+} matches a 't' followed by an 'a' followed by
+ at least one 'g', whereas \b{(tag)+} matches at least one
occurrence of 'tag'.
Note: Quantifiers are normally "greedy". They always match as much
- text as they can. For example, \bold{0+} matches the first zero it
+ text as they can. For example, \b{0+} matches the first zero it
finds and all the consecutive zeros after the first zero. Applied
to '20005', it matches'2\underline{000}5'. Quantifiers can be made
non-greedy, see setMinimal().
@@ -395,10 +395,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Parentheses allow us to group elements together so that we can
quantify and capture them. For example if we have the expression
- \bold{mail|letter|correspondence} that matches a string we know
+ \b{mail|letter|correspondence} that matches a string we know
that \e one of the words matched but not which one. Using
parentheses allows us to "capture" whatever is matched within
- their bounds, so if we used \bold{(mail|letter|correspondence)}
+ their bounds, so if we used \b{(mail|letter|correspondence)}
and matched this regexp against the string "I sent you some email"
we can use the cap() or capturedTexts() functions to extract the
matched characters, in this case 'mail'.
@@ -406,14 +406,14 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
We can use captured text within the regexp itself. To refer to the
captured text we use \e backreferences which are indexed from 1,
the same as for cap(). For example we could search for duplicate
- words in a string using \bold{\\b(\\w+)\\W+\\1\\b} which means match a
+ words in a string using \b{\\b(\\w+)\\W+\\1\\b} which means match a
word boundary followed by one or more word characters followed by
one or more non-word characters followed by the same text as the
first parenthesized expression followed by a word boundary.
If we want to use parentheses purely for grouping and not for
capturing we can use the non-capturing syntax, e.g.
- \bold{(?:green|blue)}. Non-capturing parentheses begin '(?:' and
+ \b{(?:green|blue)}. Non-capturing parentheses begin '(?:' and
end ')'. In this example we match either 'green' or 'blue' but we
do not capture the match so we only know whether or not we matched
but not which color we actually found. Using non-capturing
@@ -424,9 +424,9 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\target greedy quantifiers
- For historical reasons, quantifiers (e.g. \bold{*}) that apply to
+ For historical reasons, quantifiers (e.g. \b{*}) that apply to
capturing parentheses are more "greedy" than other quantifiers.
- For example, \bold{a*(a*)} will match "aaa" with cap(1) == "aaa".
+ For example, \b{a*(a*)} will match "aaa" with cap(1) == "aaa".
This behavior is different from what other regexp engines do
(notably, Perl). To obtain a more intuitive capturing behavior,
specify QRegExp::RegExp2 to the QRegExp constructor or call
@@ -444,54 +444,54 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Assertions make some statement about the text at the point where
they occur in the regexp but they do not match any characters. In
- the following list \bold{\e {E}} stands for any expression.
+ the following list \b{\e {E}} stands for any expression.
\table
- \row \i \bold{^}
- \i The caret signifies the beginning of the string. If you
+ \row \li \b{^}
+ \li The caret signifies the beginning of the string. If you
wish to match a literal \c{^} you must escape it by
- writing \c{\\^}. For example, \bold{^#include} will only
+ writing \c{\\^}. For example, \b{^#include} will only
match strings which \e begin with the characters '#include'.
(When the caret is the first character of a character set it
has a special meaning, see \link #sets-of-characters Sets of
Characters \endlink.)
- \row \i \bold{$}
- \i The dollar signifies the end of the string. For example
- \bold{\\d\\s*$} will match strings which end with a digit
+ \row \li \b{$}
+ \li The dollar signifies the end of the string. For example
+ \b{\\d\\s*$} will match strings which end with a digit
optionally followed by whitespace. If you wish to match a
literal \c{$} you must escape it by writing
\c{\\$}.
- \row \i \bold{\\b}
- \i A word boundary. For example the regexp
- \bold{\\bOK\\b} means match immediately after a word
+ \row \li \b{\\b}
+ \li A word boundary. For example the regexp
+ \b{\\bOK\\b} means match immediately after a word
boundary (e.g. start of string or whitespace) the letter 'O'
then the letter 'K' immediately before another word boundary
(e.g. end of string or whitespace). But note that the
assertion does not actually match any whitespace so if we
- write \bold{(\\bOK\\b)} and we have a match it will only
+ write \b{(\\bOK\\b)} and we have a match it will only
contain 'OK' even if the string is "It's \underline{OK} now".
- \row \i \bold{\\B}
- \i A non-word boundary. This assertion is true wherever
- \bold{\\b} is false. For example if we searched for
- \bold{\\Bon\\B} in "Left on" the match would fail (space
+ \row \li \b{\\B}
+ \li A non-word boundary. This assertion is true wherever
+ \b{\\b} is false. For example if we searched for
+ \b{\\Bon\\B} in "Left on" the match would fail (space
and end of string aren't non-word boundaries), but it would
match in "t\underline{on}ne".
- \row \i \bold{(?=\e E)}
- \i Positive lookahead. This assertion is true if the
+ \row \li \b{(?=\e E)}
+ \li Positive lookahead. This assertion is true if the
expression matches at this point in the regexp. For example,
- \bold{const(?=\\s+char)} matches 'const' whenever it is
+ \b{const(?=\\s+char)} matches 'const' whenever it is
followed by 'char', as in 'static \underline{const} char *'.
- (Compare with \bold{const\\s+char}, which matches 'static
+ (Compare with \b{const\\s+char}, which matches 'static
\underline{const char} *'.)
- \row \i \bold{(?!\e E)}
- \i Negative lookahead. This assertion is true if the
+ \row \li \b{(?!\e E)}
+ \li Negative lookahead. This assertion is true if the
expression does not match at this point in the regexp. For
- example, \bold{const(?!\\s+char)} matches 'const' \e except
+ example, \b{const(?!\\s+char)} matches 'const' \e except
when it is followed by 'char'.
\endtable
@@ -505,17 +505,17 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
simpler than full regexps and has only four features:
\table
- \row \i \bold{c}
- \i Any character represents itself apart from those mentioned
- below. Thus \bold{c} matches the character \e c.
- \row \i \bold{?}
- \i Matches any single character. It is the same as
- \bold{.} in full regexps.
- \row \i \bold{*}
- \i Matches zero or more of any characters. It is the
- same as \bold{.*} in full regexps.
- \row \i \bold{[...]}
- \i Sets of characters can be represented in square brackets,
+ \row \li \b{c}
+ \li Any character represents itself apart from those mentioned
+ below. Thus \b{c} matches the character \e c.
+ \row \li \b{?}
+ \li Matches any single character. It is the same as
+ \b{.} in full regexps.
+ \row \li \b{*}
+ \li Matches zero or more of any characters. It is the
+ same as \b{.*} in full regexps.
+ \row \li \b{[...]}
+ \li Sets of characters can be represented in square brackets,
similar to full regexps. Within the character class, like
outside, backslash has no special meaning.
\endtable
@@ -525,7 +525,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
wildcard.
For example if we are in wildcard mode and have strings which
- contain filenames we could identify HTML files with \bold{*.html}.
+ contain filenames we could identify HTML files with \b{*.html}.
This will match zero or more characters followed by a dot followed
by 'h', 't', 'm' and 'l'.
@@ -553,7 +553,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
(but see the \l{greedy quantifiers}{note above}). Non-greedy
matching cannot be applied to individual quantifiers, but can be
applied to all the quantifiers in the pattern. For example, to
- match the Perl regexp \bold{ro+?m} requires:
+ match the Perl regexp \b{ro+?m} requires:
\snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 2
@@ -562,7 +562,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Perl's \c{/g} option can be emulated using a \l{#cap_in_a_loop}{loop}.
- In QRegExp \bold{.} matches any character, therefore all QRegExp
+ In QRegExp \b{.} matches any character, therefore all QRegExp
regexps have the equivalent of Perl's \c{/s} option. QRegExp
does not have an equivalent to Perl's \c{/m} option, but this
can be emulated in various ways for example by splitting the input
@@ -598,7 +598,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
to Perl's split and join functions.
Note: because C++ transforms \\'s they must be written \e twice in
- code, e.g. \bold{\\b} must be written \bold{\\\\b}.
+ code, e.g. \b{\\b} must be written \b{\\\\b}.
\target code-examples
\section1 Code Examples
@@ -670,10 +670,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Wildcard matching can be convenient because of its simplicity, but
any wildcard regexp can be defined using full regexps, e.g.
- \bold{.*\\.html$}. Notice that we can't match both \c .html and \c
- .htm files with a wildcard unless we use \bold{*.htm*} which will
+ \b{.*\\.html$}. Notice that we can't match both \c .html and \c
+ .htm files with a wildcard unless we use \b{*.htm*} which will
also match 'test.html.bak'. A full regexp gives us the precision
- we need, \bold{.*\\.html?$}.
+ we need, \b{.*\\.html?$}.
QRegExp can match case insensitively using setCaseSensitivity(),
and can use non-greedy matching, see setMinimal(). By
@@ -3015,6 +3015,8 @@ int QRegExpEngine::getEscape()
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'i':
if (xmlSchemaExtensions) {
@@ -3045,12 +3047,16 @@ int QRegExpEngine::getEscape()
yyCharClass->addRange(0xf900, 0xfdcf);
yyCharClass->addRange(0xfdf0, 0xfffd);
yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff);
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
case 'C':
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'c':
if (xmlSchemaExtensions) {
@@ -3087,12 +3093,16 @@ int QRegExpEngine::getEscape()
yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff);
yyCharClass->addRange(0x0300, 0x036f);
yyCharClass->addRange(0x203f, 0x2040);
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
case 'P':
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'p':
if (xmlSchemaExtensions) {
@@ -3246,8 +3256,10 @@ int QRegExpEngine::getEscape()
} else {
error(RXERR_CATEGORY);
}
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
#endif
#ifndef QT_NO_REGEXP_ESCAPE
case 'x':
@@ -3265,20 +3277,21 @@ int QRegExpEngine::getEscape()
return Tok_Char | val;
#endif
default:
- if (prevCh >= '1' && prevCh <= '9') {
+ break;
+ }
+ if (prevCh >= '1' && prevCh <= '9') {
#ifndef QT_NO_REGEXP_BACKREF
- val = prevCh - '0';
- while (yyCh >= '0' && yyCh <= '9') {
- val = (val * 10) + (yyCh - '0');
- yyCh = getChar();
- }
- return Tok_BackRef | val;
+ val = prevCh - '0';
+ while (yyCh >= '0' && yyCh <= '9') {
+ val = (val * 10) + (yyCh - '0');
+ yyCh = getChar();
+ }
+ return Tok_BackRef | val;
#else
- error(RXERR_DISABLED);
+ error(RXERR_DISABLED);
#endif
- }
- return Tok_Char | prevCh;
}
+ return Tok_Char | prevCh;
}
#ifndef QT_NO_REGEXP_INTERVAL
@@ -3885,7 +3898,7 @@ static void invalidateEngine(QRegExpPrivate *priv)
\enum QRegExp::CaretMode
The CaretMode enum defines the different meanings of the caret
- (\bold{^}) in a regular expression. The possible values are:
+ (\b{^}) in a regular expression. The possible values are:
\value CaretAtZero
The caret corresponds to index 0 in the searched string.
@@ -4052,11 +4065,11 @@ bool QRegExp::isEmpty() const
Returns true if the regular expression is valid; otherwise returns
false. An invalid regular expression never matches.
- The pattern \bold{[a-z} is an example of an invalid pattern, since
+ The pattern \b{[a-z} is an example of an invalid pattern, since
it lacks a closing square bracket.
Note that the validity of a regexp may also depend on the setting
- of the wildcard flag, for example \bold{*.html} is a valid
+ of the wildcard flag, for example \b{*.html} is a valid
wildcard regexp but an invalid full regexp.
\sa errorString()
@@ -4111,7 +4124,7 @@ Qt::CaseSensitivity QRegExp::caseSensitivity() const
/*!
Sets case sensitive matching to \a cs.
- If \a cs is Qt::CaseSensitive, \bold{\\.txt$} matches
+ If \a cs is Qt::CaseSensitive, \b{\\.txt$} matches
\c{readme.txt} but not \c{README.TXT}.
\sa setPatternSyntax(), setPattern(), setMinimal()
@@ -4140,7 +4153,7 @@ QRegExp::PatternSyntax QRegExp::patternSyntax() const
QRegExp::RegExp.
Setting \a syntax to QRegExp::Wildcard enables simple shell-like
- \l{wildcard matching}. For example, \bold{r*.txt} matches the
+ \l{wildcard matching}. For example, \b{r*.txt} matches the
string \c{readme.txt} in wildcard mode, but does not match
\c{readme}.
@@ -4175,13 +4188,13 @@ bool QRegExp::isMinimal() const
For example, suppose we have the input string "We must be
<b>bold</b>, very <b>bold</b>!" and the pattern
- \bold{<b>.*</b>}. With the default greedy (maximal) matching,
+ \b{<b>.*</b>}. With the default greedy (maximal) matching,
the match is "We must be \underline{<b>bold</b>, very
<b>bold</b>}!". But with minimal (non-greedy) matching, the
first match is: "We must be \underline{<b>bold</b>}, very
<b>bold</b>!" and the second match is "We must be <b>bold</b>,
very \underline{<b>bold</b>}!". In practice we might use the pattern
- \bold{<b>[^<]*\</b>} instead, although this will still fail for
+ \b{<b>[^<]*\</b>} instead, although this will still fail for
nested tags.
\sa setCaseSensitivity()
@@ -4202,7 +4215,7 @@ void QRegExp::setMinimal(bool minimal)
in the start of string and end of string anchors, except that it
sets matchedLength() differently.
- For example, if the regular expression is \bold{blue}, then
+ For example, if the regular expression is \b{blue}, then
exactMatch() returns true only for input \c blue. For inputs \c
bluebell, \c blutak and \c lightblue, exactMatch() returns false
and matchedLength() will return 4, 3 and 0 respectively.
@@ -4234,7 +4247,7 @@ bool QRegExp::exactMatch(const QString &str) const
Returns the position of the first match, or -1 if there was no
match.
- The \a caretMode parameter can be used to instruct whether \bold{^}
+ The \a caretMode parameter can be used to instruct whether \b{^}
should match at index 0 or at \a offset.
You might prefer to use QString::indexOf(), QString::contains(),
@@ -4273,7 +4286,7 @@ int QRegExp::indexIn(const QString &str, int offset, CaretMode caretMode) const
Returns the position of the first match, or -1 if there was no
match.
- The \a caretMode parameter can be used to instruct whether \bold{^}
+ The \a caretMode parameter can be used to instruct whether \b{^}
should match at index 0 or at \a offset.
Although const, this function sets matchedLength(),
@@ -4358,7 +4371,7 @@ int QRegExp::captureCount() const
Some regexps can match an indeterminate number of times. For
example if the input string is "Offsets: 12 14 99 231 7" and the
- regexp, \c{rx}, is \bold{(\\d+)+}, we would hope to get a list of
+ regexp, \c{rx}, is \b{(\\d+)+}, we would hope to get a list of
all the numbers matched. However, after calling
\c{rx.indexIn(str)}, capturedTexts() will return the list ("12",
"12"), i.e. the entire match was "12" and the first subexpression
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index 46e505099a..c248477f2c 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QRingBuffer
{
public:
- inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) {
+ explicit inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) {
buffers << QByteArray();
clear();
}
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index b6bf525fb9..5ecca89229 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -89,10 +89,10 @@ QT_BEGIN_NAMESPACE
The following custom cleanup handlers exist:
\list
- \i QScopedPointerDeleter - the default, deletes the pointer using \c delete
- \i QScopedPointerArrayDeleter - deletes the pointer using \c{delete []}. Use
+ \li QScopedPointerDeleter - the default, deletes the pointer using \c delete
+ \li QScopedPointerArrayDeleter - deletes the pointer using \c{delete []}. Use
this handler for pointers that were allocated with \c{new []}.
- \i QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
+ \li QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
handler for pointers that were allocated with \c{malloc()}.
\endlist
diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp
index 6250745400..ffc8ac601d 100644
--- a/src/corelib/tools/qshareddata.cpp
+++ b/src/corelib/tools/qshareddata.cpp
@@ -86,10 +86,10 @@ QT_BEGIN_NAMESPACE
\list
- \o Define the class \c Employee to have a single data member of
+ \li Define the class \c Employee to have a single data member of
type \c {QSharedDataPointer<EmployeeData>}.
- \o Define the \c EmployeeData class derived from \l QSharedData to
+ \li Define the \c EmployeeData class derived from \l QSharedData to
contain all the data members you would normally have put in the
\c Employee class.
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index 4c94f899e7..b276d2d2e0 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -186,10 +186,10 @@ void QSize::transpose()
height, according to the specified \a mode:
\list
- \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
- \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
as large as possible inside (\a width, \a height), preserving the aspect ratio.
- \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
as small as possible outside (\a width, \a height), preserving the aspect ratio.
\endlist
@@ -614,10 +614,10 @@ void QSizeF::transpose()
height, according to the specified \a mode.
\list
- \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
- \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
as large as possible inside (\a width, \a height), preserving the aspect ratio.
- \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
as small as possible outside (\a width, \a height), preserving the aspect ratio.
\endlist
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index e73c52980f..083abcbaad 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -606,12 +606,12 @@ const QString::Null QString::null = { };
toLatin1(), toUtf8(), and toLocal8Bit().
\list
- \o toAscii() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
- \o toLatin1() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
- \o toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a
+ \li toAscii() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
+ \li toLatin1() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
+ \li toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a
superset of US-ASCII (ANSI X3.4-1986) that supports the entire
Unicode character set through multibyte sequences.
- \o toLocal8Bit() returns an 8-bit string using the system's local
+ \li toLocal8Bit() returns an 8-bit string using the system's local
encoding.
\endlist
@@ -629,9 +629,9 @@ const QString::Null QString::null = { };
conversions by defining the following two preprocessor symbols:
\list
- \o \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
+ \li \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
C string literals and pointers to Unicode.
- \o \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
+ \li \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
to C strings.
\endlist
@@ -655,10 +655,10 @@ const QString::Null QString::null = { };
\table 100 %
\header
- \o Note for C Programmers
+ \li Note for C Programmers
\row
- \o
+ \li
Due to C++'s type system and the fact that QString is
\l{implicitly shared}, QStrings may be treated like \c{int}s or
other basic types. For example:
@@ -697,12 +697,12 @@ const QString::Null QString::null = { };
following:
\table
- \header \o Format \o Meaning
- \row \o \c e \o format as [-]9.9e[+|-]999
- \row \o \c E \o format as [-]9.9E[+|-]999
- \row \o \c f \o format as [-]9.9
- \row \o \c g \o use \c e or \c f format, whichever is the most concise
- \row \o \c G \o use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
A \e precision is also specified with the argument \e format. For
@@ -2795,7 +2795,7 @@ struct QStringCapture
\snippet doc/src/snippets/qstring/main.cpp 42
For regular expressions containing \l{capturing parentheses},
- occurrences of \bold{\\1}, \bold{\\2}, ..., in \a after are replaced
+ occurrences of \b{\\1}, \b{\\2}, ..., in \a after are replaced
with \a{rx}.cap(1), cap(2), ...
\snippet doc/src/snippets/qstring/main.cpp 43
@@ -6065,7 +6065,7 @@ QStringList QString::split(QChar sep, SplitBehavior behavior, Qt::CaseSensitivit
\snippet doc/src/snippets/qstring/main.cpp 60
Here's a third example where we use a zero-length assertion,
- \bold{\\b} (word boundary), to split the string into an
+ \b{\\b} (word boundary), to split the string into an
alternating sequence of non-word and word tokens:
\snippet doc/src/snippets/qstring/main.cpp 61
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index a352045a7d..b4ec0c6498 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -342,7 +342,7 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &b
\snippet doc/src/snippets/qstringlist/main.cpp 14
For regular expressions that contain \l{capturing parentheses},
- occurrences of \bold{\\1}, \bold{\\2}, ..., in \a after are
+ occurrences of \b{\\1}, \b{\\2}, ..., in \a after are
replaced with \a{rx}.cap(1), \a{rx}.cap(2), ...
For example:
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index 1a0579a077..e1dc2bee9a 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -69,13 +69,13 @@
structure. The main differences between the two classes are:
\list
- \o QVarLengthArray's API is much more low-level. It provides no
+ \li QVarLengthArray's API is much more low-level. It provides no
iterators and lacks much of QVector's functionality.
- \o QVarLengthArray doesn't initialize the memory if the value is
+ \li QVarLengthArray doesn't initialize the memory if the value is
a basic type. (QVector always does.)
- \o QVector uses \l{implicit sharing} as a memory optimization.
+ \li QVector uses \l{implicit sharing} as a memory optimization.
QVarLengthArray doesn't provide that feature; however, it
usually produces slightly better performance due to reduced
overhead, especially in tight loops.
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 3efe695559..75c219bbc9 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -108,21 +108,21 @@ int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive
similar functionality. Here's an overview:
\list
- \i For most purposes, QList is the right class to use. Operations
+ \li For most purposes, QList is the right class to use. Operations
like prepend() and insert() are usually faster than with
QVector because of the way QList stores its items in memory
(see \l{Algorithmic Complexity} for details),
and its index-based API is more convenient than QLinkedList's
iterator-based API. It also expands to less code in your
executable.
- \i If you need a real linked list, with guarantees of \l{constant
+ \li If you need a real linked list, with guarantees of \l{constant
time} insertions in the middle of the list and iterators to
items rather than indexes, use QLinkedList.
- \i If you want the items to occupy adjacent memory positions, or
+ \li If you want the items to occupy adjacent memory positions, or
if your items are larger than a pointer and you want to avoid
the overhead of allocating them on the heap individually at
insertion time, then use QVector.
- \i If you want a low-level variable-size array, QVarLengthArray
+ \li If you want a low-level variable-size array, QVarLengthArray
may be sufficient.
\endlist
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index d6bdc19d51..8863766f40 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -331,10 +331,10 @@ QDBusMessage QDBusMessagePrivate::makeLocalReply(const QDBusConnectionPrivate &c
messages (MessageType) that can occur on the bus:
\list
- \o Method calls
- \o Method return values
- \o Signal emissions
- \o Error codes
+ \li Method calls
+ \li Method return values
+ \li Signal emissions
+ \li Error codes
\endlist
Objects of this type are created with the static createError(),
diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp
index 78b64c4772..b9694ca205 100644
--- a/src/dbus/qdbuspendingreply.cpp
+++ b/src/dbus/qdbuspendingreply.cpp
@@ -60,9 +60,9 @@
important differences:
\list
- \o QDBusReply accepts exactly one return type, whereas
+ \li QDBusReply accepts exactly one return type, whereas
QDBusPendingReply can have from 1 to 8 types
- \o QDBusReply only works on already completed replies, whereas
+ \li QDBusReply only works on already completed replies, whereas
QDBusPendingReply allows one to wait for replies from pending
calls
\endlist
diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp
index 749d68fad5..d45fa8b8ca 100644
--- a/src/dbus/qdbusservicewatcher.cpp
+++ b/src/dbus/qdbusservicewatcher.cpp
@@ -153,9 +153,9 @@ void QDBusServiceWatcherPrivate::removeService(const QString &service)
modes:
\list
- \o Watching for service registration only.
- \o Watching for service unregistration only.
- \o Watching for any kind of service ownership change (the default mode).
+ \li Watching for service registration only.
+ \li Watching for service unregistration only.
+ \li Watching for any kind of service ownership change (the default mode).
\endlist
Besides being created or deleted, services may change owners without a
diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp
index 71edee1b2b..bed07692b8 100644
--- a/src/dbus/qdbusutil.cpp
+++ b/src/dbus/qdbusutil.cpp
@@ -348,11 +348,11 @@ namespace QDBusUtil
Valid interface names must:
\list
- \o not be empty
- \o not exceed 255 characters in length
- \o be composed of dot-separated string components that contain only ASCII letters, digits
+ \li not be empty
+ \li not exceed 255 characters in length
+ \li be composed of dot-separated string components that contain only ASCII letters, digits
and the underscore ("_") character
- \o contain at least two such components
+ \li contain at least two such components
\endlist
*/
bool isValidInterfaceName(const QString& ifaceName)
@@ -408,11 +408,11 @@ namespace QDBusUtil
A valid bus name is either a valid unique connection name or follows the rules:
\list
- \o is not empty
- \o does not exceed 255 characters in length
- \o be composed of dot-separated string components that contain only ASCII letters, digits,
+ \li is not empty
+ \li does not exceed 255 characters in length
+ \li be composed of dot-separated string components that contain only ASCII letters, digits,
hyphens or underscores ("_"), but don't start with a digit
- \o contains at least two such elements
+ \li contains at least two such elements
\endlist
\sa isValidUniqueConnectionName()
@@ -481,10 +481,10 @@ namespace QDBusUtil
Valid object paths follow the rules:
\list
- \o start with the slash character ("/")
- \o do not end in a slash, unless the path is just the initial slash
- \o do not contain any two slashes in sequence
- \o contain slash-separated parts, each of which is composed of ASCII letters, digits and
+ \li start with the slash character ("/")
+ \li do not end in a slash, unless the path is just the initial slash
+ \li do not contain any two slashes in sequence
+ \li contain slash-separated parts, each of which is composed of ASCII letters, digits and
underscores ("_")
\endlist
*/
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 37e7a1dbb4..aa47616161 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -77,10 +77,10 @@ QT_BEGIN_NAMESPACE
braille displays. Clients and servers communicate in the following way:
\list
- \o \e{AT Servers} notify the clients about events through calls to the
+ \li \e{AT Servers} notify the clients about events through calls to the
updateAccessibility() function.
- \o \e{AT Clients} request information about the objects in the server.
+ \li \e{AT Clients} request information about the objects in the server.
The QAccessibleInterface class is the core interface, and encapsulates
this information in a pure virtual API. Implementations of the interface
are provided by Qt through the queryAccessibleInterface() API.
@@ -650,8 +650,6 @@ void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
{
Q_ASSERT(object);
- qWarning("QAccessible::updateAccessibility is deprecated.");
-
QAccessibleEvent event = QAccessibleEvent(reason, object, child);
updateAccessibility(event);
}
@@ -750,12 +748,12 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const
The AT client uses three basic concepts to acquire information
about any accessible object in an application:
\list
- \i \e Properties The client can read information about
+ \li \e Properties The client can read information about
accessible objects. In some cases the client can also modify these
properties; such as text in a line edit.
- \i \e Actions The client can invoke actions like pressing a button
+ \li \e Actions The client can invoke actions like pressing a button
or .
- \i \e{Relationships and Navigation} The client can traverse from one
+ \li \e{Relationships and Navigation} The client can traverse from one
accessible object to another, using the relationships between objects.
\endlist
@@ -1198,11 +1196,23 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
if (iface->object()) {
d << "obj=" << iface->object();
}
- if (iface->state().invisible) {
- d << "invisible";
- } else {
+ QStringList stateStrings;
+ QAccessible::State st = iface->state();
+ if (st.focusable)
+ stateStrings << QLatin1String("focusable");
+ if (st.focused)
+ stateStrings << QLatin1String("focused");
+ if (st.selected)
+ stateStrings << QLatin1String("selected");
+ if (st.invisible)
+ stateStrings << QLatin1String("invisible");
+
+ if (!stateStrings.isEmpty())
+ d << stateStrings.join(QLatin1String("|"));
+
+ if (!st.invisible)
d << "rect=" << iface->rect();
- }
+
} else {
d << " invalid";
}
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index a72b91a90f..6ad1bb9da9 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -336,7 +336,7 @@ public:
static QAccessibleInterface *queryAccessibleInterface(QObject *);
- static void updateAccessibility(QObject *object, int child, Event reason);
+ QT_DEPRECATED static void updateAccessibility(QObject *object, int child, Event reason);
static void updateAccessibility(const QAccessibleEvent &event);
static bool isActive();
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index db3028b371..d3dafb8820 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -371,14 +371,14 @@ QT_BEGIN_NAMESPACE
In general you should use one of the predefined action names, unless describing an action that does not fit these:
\table
- \header \o Action name \o Description
- \row \o \l checkAction() \o checks the item (checkbox, radio button, ...)
- \row \o \l decreaseAction() \o decrease the value of the accessible (e.g. spinbox)
- \row \o \l increaseAction() \o increase the value of the accessible (e.g. spinbox)
- \row \o \l pressAction() \o press or click or activate the accessible (should correspont to clicking the object with the mouse)
- \row \o \l setFocusAction() \o set the focus to this accessible
- \row \o \l showMenuAction() \o show a context menu, corresponds to right-clicks
- \row \o \l uncheckAction() \o uncheck the item (checkbox, radio button, ...)
+ \header \li Action name \li Description
+ \row \li \l checkAction() \li checks the item (checkbox, radio button, ...)
+ \row \li \l decreaseAction() \li decrease the value of the accessible (e.g. spinbox)
+ \row \li \l increaseAction() \li increase the value of the accessible (e.g. spinbox)
+ \row \li \l pressAction() \li press or click or activate the accessible (should correspont to clicking the object with the mouse)
+ \row \li \l setFocusAction() \li set the focus to this accessible
+ \row \li \l showMenuAction() \li show a context menu, corresponds to right-clicks
+ \row \li \l uncheckAction() \li uncheck the item (checkbox, radio button, ...)
\endtable
In order to invoke the action, \l doAction() is called with an action name.
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index f83e7e60c9..34a33aa0f0 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -23,8 +23,6 @@ HEADERS += \
image/qpixmapcache_p.h \
image/qplatformpixmap_qpa.h \
image/qimagepixmapcleanuphooks_p.h \
- image/qvolatileimage_p.h \
- image/qvolatileimagedata_p.h
SOURCES += \
image/qbitmap.cpp \
@@ -42,13 +40,10 @@ SOURCES += \
image/qpixmap_raster.cpp \
image/qpixmap_blitter.cpp \
image/qnativeimage.cpp \
- image/qimagepixmapcleanuphooks.cpp \
- image/qvolatileimage.cpp
+ image/qimagepixmapcleanuphooks.cpp
win32: SOURCES += image/qpixmap_win.cpp
-SOURCES += image/qvolatileimagedata.cpp
-
# Built-in image format support
HEADERS += \
image/qbmphandler_p.h \
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 23d212cc92..3e53b04728 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -327,17 +327,17 @@ bool QImageData::checkForAlphaPixels() const
formats:
\table
- \header \o Format \o Description \o Qt's support
- \row \o BMP \o Windows Bitmap \o Read/write
- \row \o GIF \o Graphic Interchange Format (optional) \o Read
- \row \o JPG \o Joint Photographic Experts Group \o Read/write
- \row \o JPEG \o Joint Photographic Experts Group \o Read/write
- \row \o PNG \o Portable Network Graphics \o Read/write
- \row \o PBM \o Portable Bitmap \o Read
- \row \o PGM \o Portable Graymap \o Read
- \row \o PPM \o Portable Pixmap \o Read/write
- \row \o XBM \o X11 Bitmap \o Read/write
- \row \o XPM \o X11 Pixmap \o Read/write
+ \header \li Format \li Description \li Qt's support
+ \row \li BMP \li Windows Bitmap \li Read/write
+ \row \li GIF \li Graphic Interchange Format (optional) \li Read
+ \row \li JPG \li Joint Photographic Experts Group \li Read/write
+ \row \li JPEG \li Joint Photographic Experts Group \li Read/write
+ \row \li PNG \li Portable Network Graphics \li Read/write
+ \row \li PBM \li Portable Bitmap \li Read
+ \row \li PGM \li Portable Graymap \li Read
+ \row \li PPM \li Portable Pixmap \li Read/write
+ \row \li XBM \li X11 Bitmap \li Read/write
+ \row \li XPM \li X11 Pixmap \li Read/write
\endtable
\section1 Image Information
@@ -347,11 +347,11 @@ bool QImageData::checkForAlphaPixels() const
\table
\header
- \o \o Available Functions
+ \li \li Available Functions
\row
- \o Geometry
- \o
+ \li Geometry
+ \li
The size(), width(), height(), dotsPerMeterX(), and
dotsPerMeterY() functions provide information about the image size
@@ -365,8 +365,8 @@ bool QImageData::checkForAlphaPixels() const
setOffset() function.
\row
- \o Colors
- \o
+ \li Colors
+ \li
The color of a pixel can be retrieved by passing its coordinates
to the pixel() function. The pixel() function returns the color
@@ -392,8 +392,8 @@ bool QImageData::checkForAlphaPixels() const
sections.
\row
- \o Text
- \o
+ \li Text
+ \li
The text() function returns the image text associated with the
given text key. An image's text keys can be retrieved using the
@@ -401,8 +401,8 @@ bool QImageData::checkForAlphaPixels() const
image's text.
\row
- \o Low-level information
- \o
+ \li Low-level information
+ \li
The depth() function returns the depth of the image. The supported
depths are 1 (monochrome), 8, 16, 24 and 32 bits. The
@@ -434,10 +434,10 @@ bool QImageData::checkForAlphaPixels() const
\table
\header
- \o {2,1}32-bit
+ \li {2,1}32-bit
\row
- \o \inlineimage qimage-32bit_scaled.png
- \o
+ \li \inlineimage qimage-32bit_scaled.png
+ \li
\snippet doc/src/snippets/code/src_gui_image_qimage.cpp 0
\endtable
@@ -455,10 +455,10 @@ bool QImageData::checkForAlphaPixels() const
\table
\header
- \o {2,1} 8-bit
+ \li {2,1} 8-bit
\row
- \o \inlineimage qimage-8bit_scaled.png
- \o
+ \li \inlineimage qimage-8bit_scaled.png
+ \li
\snippet doc/src/snippets/code/src_gui_image_qimage.cpp 1
\endtable
@@ -529,28 +529,28 @@ bool QImageData::checkForAlphaPixels() const
in-place:
\table
- \header \o Function \o Description
+ \header \li Function \li Description
\row
- \o setDotsPerMeterX()
- \o Defines the aspect ratio by setting the number of pixels that fit
+ \li setDotsPerMeterX()
+ \li Defines the aspect ratio by setting the number of pixels that fit
horizontally in a physical meter.
\row
- \o setDotsPerMeterY()
- \o Defines the aspect ratio by setting the number of pixels that fit
+ \li setDotsPerMeterY()
+ \li Defines the aspect ratio by setting the number of pixels that fit
vertically in a physical meter.
\row
- \o fill()
- \o Fills the entire image with the given pixel value.
+ \li fill()
+ \li Fills the entire image with the given pixel value.
\row
- \o invertPixels()
- \o Inverts all pixel values in the image using the given InvertMode value.
+ \li invertPixels()
+ \li Inverts all pixel values in the image using the given InvertMode value.
\row
- \o setColorTable()
- \o Sets the color table used to translate color indexes. Only
+ \li setColorTable()
+ \li Sets the color table used to translate color indexes. Only
monochrome and 8-bit formats.
\row
- \o setColorCount()
- \o Resizes the color table. Only monochrome and 8-bit formats.
+ \li setColorCount()
+ \li Resizes the color table. Only monochrome and 8-bit formats.
\endtable
@@ -3794,11 +3794,11 @@ bool QImage::isGrayscale() const
\image qimage-scaling.png
\list
- \i If \a aspectRatioMode is Qt::IgnoreAspectRatio, the image
+ \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the image
is scaled to \a size.
- \i If \a aspectRatioMode is Qt::KeepAspectRatio, the image is
+ \li If \a aspectRatioMode is Qt::KeepAspectRatio, the image is
scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
- \i If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
+ \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
the image is scaled to a rectangle as small as possible
outside \a size, preserving the aspect ratio.
\endlist
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 4a9a9b00f4..870784f638 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -703,22 +703,22 @@ QByteArray QImageReader::format() const
\list
- \o Image plugins are queried first, based on either the optional format
+ \li Image plugins are queried first, based on either the optional format
string, or the file name suffix (if the source device is a file). No
content detection is done at this stage. QImageReader will choose the
first plugin that supports reading for this format.
- \o If no plugin supports the image format, Qt's built-in handlers are
+ \li If no plugin supports the image format, Qt's built-in handlers are
checked based on either the optional format string, or the file name
suffix.
- \o If no capable plugins or built-in handlers are found, each plugin is
+ \li If no capable plugins or built-in handlers are found, each plugin is
tested by inspecting the content of the data stream.
- \o If no plugins could detect the image format based on data contents,
+ \li If no plugins could detect the image format based on data contents,
each built-in image handler is tested by inspecting the contents.
- \o Finally, if all above approaches fail, QImageReader will report failure
+ \li Finally, if all above approaches fail, QImageReader will report failure
when trying to read the image.
\endlist
@@ -1423,18 +1423,18 @@ QByteArray QImageReader::imageFormat(QIODevice *device)
By default, Qt can read the following formats:
\table
- \header \o Format \o Description
- \row \o BMP \o Windows Bitmap
- \row \o GIF \o Graphic Interchange Format (optional)
- \row \o JPG \o Joint Photographic Experts Group
- \row \o JPEG \o Joint Photographic Experts Group
- \row \o PNG \o Portable Network Graphics
- \row \o PBM \o Portable Bitmap
- \row \o PGM \o Portable Graymap
- \row \o PPM \o Portable Pixmap
- \row \o XBM \o X11 Bitmap
- \row \o XPM \o X11 Pixmap
- \row \o SVG \o Scalable Vector Graphics
+ \header \li Format \li Description
+ \row \li BMP \li Windows Bitmap
+ \row \li GIF \li Graphic Interchange Format (optional)
+ \row \li JPG \li Joint Photographic Experts Group
+ \row \li JPEG \li Joint Photographic Experts Group
+ \row \li PNG \li Portable Network Graphics
+ \row \li PBM \li Portable Bitmap
+ \row \li PGM \li Portable Graymap
+ \row \li PPM \li Portable Pixmap
+ \row \li XBM \li X11 Bitmap
+ \row \li XPM \li X11 Pixmap
+ \row \li SVG \li Scalable Vector Graphics
\endtable
Reading and writing SVG files is supported through Qt's
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 966017452c..8395f9d216 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -653,14 +653,14 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
By default, Qt can write the following formats:
\table
- \header \o Format \o Description
- \row \o BMP \o Windows Bitmap
- \row \o JPG \o Joint Photographic Experts Group
- \row \o JPEG \o Joint Photographic Experts Group
- \row \o PNG \o Portable Network Graphics
- \row \o PPM \o Portable Pixmap
- \row \o XBM \o X11 Bitmap
- \row \o XPM \o X11 Pixmap
+ \header \li Format \li Description
+ \row \li BMP \li Windows Bitmap
+ \row \li JPG \li Joint Photographic Experts Group
+ \row \li JPEG \li Joint Photographic Experts Group
+ \row \li PNG \li Portable Network Graphics
+ \row \li PPM \li Portable Pixmap
+ \row \li XBM \li X11 Bitmap
+ \row \li XPM \li X11 Pixmap
\endtable
Reading and writing SVG files is supported through Qt's
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 1f325f5b6b..65b9d62dfa 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1047,11 +1047,11 @@ bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags fla
\image qimage-scaling.png
\list
- \i If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
+ \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
is scaled to \a size.
- \i If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
+ \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
- \i If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
+ \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
the pixmap is scaled to a rectangle as small as possible
outside \a size, preserving the aspect ratio.
\endlist
@@ -1268,17 +1268,17 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
formats:
\table
- \header \o Format \o Description \o Qt's support
- \row \o BMP \o Windows Bitmap \o Read/write
- \row \o GIF \o Graphic Interchange Format (optional) \o Read
- \row \o JPG \o Joint Photographic Experts Group \o Read/write
- \row \o JPEG \o Joint Photographic Experts Group \o Read/write
- \row \o PNG \o Portable Network Graphics \o Read/write
- \row \o PBM \o Portable Bitmap \o Read
- \row \o PGM \o Portable Graymap \o Read
- \row \o PPM \o Portable Pixmap \o Read/write
- \row \o XBM \o X11 Bitmap \o Read/write
- \row \o XPM \o X11 Pixmap \o Read/write
+ \header \li Format \li Description \li Qt's support
+ \row \li BMP \li Windows Bitmap \li Read/write
+ \row \li GIF \li Graphic Interchange Format (optional) \li Read
+ \row \li JPG \li Joint Photographic Experts Group \li Read/write
+ \row \li JPEG \li Joint Photographic Experts Group \li Read/write
+ \row \li PNG \li Portable Network Graphics \li Read/write
+ \row \li PBM \li Portable Bitmap \li Read
+ \row \li PGM \li Portable Graymap \li Read
+ \row \li PPM \li Portable Pixmap \li Read/write
+ \row \li XBM \li X11 Bitmap \li Read/write
+ \row \li XPM \li X11 Pixmap \li Read/write
\endtable
\section1 Pixmap Information
@@ -1288,17 +1288,17 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
\table
\header
- \o \o Available Functions
+ \li \li Available Functions
\row
- \o Geometry
- \o
+ \li Geometry
+ \li
The size(), width() and height() functions provide information
about the pixmap's size. The rect() function returns the image's
enclosing rectangle.
\row
- \o Alpha component
- \o
+ \li Alpha component
+ \li
The hasAlphaChannel() returns true if the pixmap has a format that
respects the alpha channel, otherwise returns false. The hasAlpha(),
@@ -1313,8 +1313,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
QBitmap) for the pixmap based on a given color.
\row
- \o Low-level information
- \o
+ \li Low-level information
+ \li
The depth() function returns the depth of the pixmap. The
defaultDepth() function returns the default depth, i.e. the depth
diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp
deleted file mode 100644
index 8122c9cfe8..0000000000
--- a/src/gui/image/qvolatileimage.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qvolatileimage_p.h"
-#include "qvolatileimagedata_p.h"
-#include <QtGui/private/qpaintengine_raster_p.h>
-#include <QtGui/qplatformpixmap_qpa.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVolatileImagePaintEnginePrivate : public QRasterPaintEnginePrivate
-{
-public:
- QVolatileImagePaintEnginePrivate() { }
- QVolatileImage *img;
-};
-
-class QVolatileImagePaintEngine : public QRasterPaintEngine
-{
- Q_DECLARE_PRIVATE(QVolatileImagePaintEngine)
-
-public:
- QVolatileImagePaintEngine(QPaintDevice *device, QVolatileImage *img);
- bool begin(QPaintDevice *device);
- bool end();
- void drawPixmap(const QPointF &p, const QPixmap &pm);
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
-};
-
-QVolatileImage::QVolatileImage()
- : d(new QVolatileImageData)
-{
-}
-
-QVolatileImage::QVolatileImage(int w, int h, QImage::Format format)
- : d(new QVolatileImageData(w, h, format))
-{
-}
-
-QVolatileImage::QVolatileImage(const QImage &sourceImage)
- : d(new QVolatileImageData(sourceImage))
-{
-}
-
-QVolatileImage::QVolatileImage(void *nativeImage, void *nativeMask)
- : d(new QVolatileImageData(nativeImage, nativeMask))
-{
-}
-
-// Need non-inline, non-autogenerated copy ctor, dtor, op= to keep the
-// fwd declared QSharedData working.
-
-QVolatileImage::QVolatileImage(const QVolatileImage &other)
- : d(other.d)
-{
-}
-
-QVolatileImage::~QVolatileImage()
-{
-}
-
-QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs)
-{
- d = rhs.d;
- return *this;
-}
-
-bool QVolatileImage::isNull() const
-{
- return d->image.isNull();
-}
-
-QImage::Format QVolatileImage::format() const
-{
- return d->image.format();
-}
-
-int QVolatileImage::width() const
-{
- return d->image.width();
-}
-
-int QVolatileImage::height() const
-{
- return d->image.height();
-}
-
-int QVolatileImage::bytesPerLine() const
-{
- return d->image.bytesPerLine();
-}
-
-int QVolatileImage::byteCount() const
-{
- return d->image.byteCount();
-}
-
-int QVolatileImage::depth() const
-{
- return d->image.depth();
-}
-
-bool QVolatileImage::hasAlphaChannel() const
-{
- return d->image.hasAlphaChannel();
-}
-
-void QVolatileImage::beginDataAccess() const
-{
- d->beginDataAccess();
-}
-
-void QVolatileImage::endDataAccess(bool readOnly) const
-{
- d->endDataAccess(readOnly);
-}
-
-/*!
- Access to pixel data via bits() or constBits() should be guarded by
- begin/endDataAccess().
- */
-uchar *QVolatileImage::bits()
-{
- return d->image.bits();
-}
-
-const uchar *QVolatileImage::constBits() const
-{
- return d->image.constBits();
-}
-
-bool QVolatileImage::ensureFormat(QImage::Format format)
-{
- return d->ensureFormat(format);
-}
-
-/*!
- This will always perform a copy of the pixel data.
- */
-QImage QVolatileImage::toImage() const
-{
- d->beginDataAccess();
- QImage newImage = d->image.copy(); // no sharing allowed
- d->endDataAccess(true);
- return newImage;
-}
-
-/*!
- Returns a reference to the image that is potentially using some native
- buffer internally. Access to the image's pixel data should be guarded by
- begin/endDataAccess(). Use it when there is a need for QImage APIs not provided
- by this class. The returned QImage must never be shared or assigned to.
- */
-QImage &QVolatileImage::imageRef() // non-const, in order to cause a detach
-{
- d->ensureImage();
- return d->image;
-}
-
-void *QVolatileImage::duplicateNativeImage() const
-{
- return d->duplicateNativeImage();
-}
-
-void QVolatileImage::fill(uint pixelValue)
-{
- beginDataAccess();
- imageRef().fill(pixelValue);
- endDataAccess();
- d->ensureImage();
-}
-
-void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect)
-{
- if (source->isNull()) {
- return;
- }
- QRect r = rect;
- if (rect.isNull()) {
- r = QRect(0, 0, source->width(), source->height());
- }
- source->beginDataAccess();
- QImage &srcImgRef(source->imageRef());
- int srcbpl = srcImgRef.bytesPerLine();
- int srcbpp = srcImgRef.depth() / 8;
- const uchar *sptr = srcImgRef.constBits() + r.y() * srcbpl;
- beginDataAccess();
- QImage &dstImgRef(imageRef());
- int dstbpl = dstImgRef.bytesPerLine();
- uchar *dptr = dstImgRef.bits();
- for (int y = 0; y < r.height(); ++y) {
- qMemCopy(dptr, sptr + r.x() * srcbpp, r.width() * srcbpp);
- sptr += srcbpl;
- dptr += dstbpl;
- }
- endDataAccess();
- source->endDataAccess(true);
-}
-
-/*!
- To be called from the PlatformPixmap's paintEngine().
- */
-QPaintEngine *QVolatileImage::paintEngine()
-{
- if (!d->pengine) {
- d->pengine = new QVolatileImagePaintEngine(&imageRef(), this);
- }
- return d->pengine;
-}
-
-QVolatileImagePaintEngine::QVolatileImagePaintEngine(QPaintDevice *device,
- QVolatileImage *img)
- : QRasterPaintEngine(*(new QVolatileImagePaintEnginePrivate), device)
-{
- Q_D(QVolatileImagePaintEngine);
- d->img = img;
-}
-
-bool QVolatileImagePaintEngine::begin(QPaintDevice *device)
-{
- Q_D(QVolatileImagePaintEngine);
- d->img->beginDataAccess();
- return QRasterPaintEngine::begin(device);
-}
-
-bool QVolatileImagePaintEngine::end()
-{
- Q_D(QVolatileImagePaintEngine);
- bool ret = QRasterPaintEngine::end();
- d->img->endDataAccess();
- return ret;
-}
-
-// For non-RasterClass pixmaps drawPixmap() would call toImage() which is slow in
-// our case. Therefore drawPixmap() is rerouted to drawImage().
-
-void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
-{
- QRasterPaintEngine::drawPixmap(p, pm);
-}
-
-void QVolatileImagePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- QRasterPaintEngine::drawPixmap(r, pm, sr);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h
deleted file mode 100644
index 808def7c32..0000000000
--- a/src/gui/image/qvolatileimage_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVOLATILEIMAGE_P_H
-#define QVOLATILEIMAGE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qimage.h>
-#include <QtCore/qshareddata.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVolatileImageData;
-
-class Q_GUI_EXPORT QVolatileImage
-{
-public:
- QVolatileImage();
- QVolatileImage(int w, int h, QImage::Format format);
- explicit QVolatileImage(const QImage &sourceImage);
- explicit QVolatileImage(void *nativeImage, void *nativeMask = 0);
- QVolatileImage(const QVolatileImage &other);
- ~QVolatileImage();
- QVolatileImage &operator=(const QVolatileImage &rhs);
-
- bool isNull() const;
- QImage::Format format() const;
- int width() const;
- int height() const;
- int bytesPerLine() const;
- int byteCount() const;
- int depth() const;
- bool hasAlphaChannel() const;
- void beginDataAccess() const;
- void endDataAccess(bool readOnly = false) const;
- uchar *bits();
- const uchar *constBits() const;
- bool ensureFormat(QImage::Format format);
- QImage toImage() const;
- QImage &imageRef();
- QPaintEngine *paintEngine();
- void fill(uint pixelValue);
- void *duplicateNativeImage() const;
- void copyFrom(QVolatileImage *source, const QRect &rect);
-
-private:
- QSharedDataPointer<QVolatileImageData> d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QVOLATILEIMAGE_P_H
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 9c5f3b10da..06773f58b5 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -56,7 +56,8 @@ HEADERS += \
kernel/qtouchdevice_p.h \
kernel/qplatformsharedgraphicscache_qpa.h \
kernel/qplatformdialoghelper_qpa.h \
- kernel/qplatformservices_qpa.h
+ kernel/qplatformservices_qpa.h \
+ kernel/qplatformscreenpageflipper_qpa.h
SOURCES += \
kernel/qclipboard_qpa.cpp \
@@ -66,6 +67,7 @@ SOURCES += \
kernel/qwindowsysteminterface_qpa.cpp \
kernel/qplatforminputcontext_qpa.cpp \
kernel/qplatformintegration_qpa.cpp \
+ kernel/qplatformdrag_qpa.cpp \
kernel/qplatformscreen_qpa.cpp \
kernel/qplatformintegrationfactory_qpa.cpp \
kernel/qplatformintegrationplugin_qpa.cpp \
@@ -99,7 +101,8 @@ SOURCES += \
kernel/qtouchdevice.cpp \
kernel/qplatformsharedgraphicscache_qpa.cpp \
kernel/qplatformdialoghelper_qpa.cpp \
- kernel/qplatformservices_qpa.cpp
+ kernel/qplatformservices_qpa.cpp \
+ kernel/qplatformscreenpageflipper_qpa.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, egl) {
HEADERS += \
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index 8e881aabc7..27179cf141 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -86,18 +86,18 @@ QT_BEGIN_NAMESPACE
\list
- \i The X11 Window System has the concept of a separate selection
+ \li The X11 Window System has the concept of a separate selection
and clipboard. When text is selected, it is immediately available
as the global mouse selection. The global mouse selection may
later be copied to the clipboard. By convention, the middle mouse
button is used to paste the global mouse selection.
- \i X11 also has the concept of ownership; if you change the
+ \li X11 also has the concept of ownership; if you change the
selection within a window, X11 will only notify the owner and the
previous owner of the change, i.e. it will not notify all
applications that the selection or clipboard data changed.
- \i Lastly, the X11 clipboard is event driven, i.e. the clipboard
+ \li Lastly, the X11 clipboard is event driven, i.e. the clipboard
will not function properly if the event loop is not running.
Similarly, it is recommended that the contents of the clipboard
are stored or retrieved in direct response to user-input events,
@@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
store or retrieve the clipboard contents in response to timer or
non-user-input events.
- \i Since there is no standard way to copy and paste files between
+ \li Since there is no standard way to copy and paste files between
applications on X11, various MIME types and conventions are currently
in use. For instance, Nautilus expects files to be supplied with a
\c{x-special/gnome-copied-files} MIME type with data beginning with
@@ -123,12 +123,12 @@ QT_BEGIN_NAMESPACE
\list
- \i Windows and Mac OS X do not support the global mouse
+ \li Windows and Mac OS X do not support the global mouse
selection; they only supports the global clipboard, i.e. they
only add text to the clipboard when an explicit copy or cut is
made.
- \i Windows and Mac OS X does not have the concept of ownership;
+ \li Windows and Mac OS X does not have the concept of ownership;
the clipboard is a fully global resource so all applications are
notified of changes.
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 77eb1e1e9c..f16e5c85de 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE
To set or get the position of the mouse cursor use the static
methods QCursor::pos() and QCursor::setPos().
- \bold{Note:} It is possible to create a QCursor before
+ \b{Note:} It is possible to create a QCursor before
QGuiApplication, but it is not useful except as a place-holder for a
real QCursor created after QGuiApplication. Attempting to use a
QCursor that was created before QGuiApplication will result in a
@@ -104,50 +104,50 @@ QT_BEGIN_NAMESPACE
theme, while others will use an internal bitmap cursor.
\table
- \header \o Shape \o Qt::CursorShape Value \o Cursor Name
- \o Shape \o Qt::CursorShape Value \o Cursor Name
- \row \o \inlineimage cursor-arrow.png
- \o Qt::ArrowCursor \o \c left_ptr
- \o \inlineimage cursor-sizev.png
- \o Qt::SizeVerCursor \o \c size_ver
- \row \o \inlineimage cursor-uparrow.png
- \o Qt::UpArrowCursor \o \c up_arrow
- \o \inlineimage cursor-sizeh.png
- \o Qt::SizeHorCursor \o \c size_hor
- \row \o \inlineimage cursor-cross.png
- \o Qt::CrossCursor \o \c cross
- \o \inlineimage cursor-sizeb.png
- \o Qt::SizeBDiagCursor \o \c size_bdiag
- \row \o \inlineimage cursor-ibeam.png
- \o Qt::IBeamCursor \o \c ibeam
- \o \inlineimage cursor-sizef.png
- \o Qt::SizeFDiagCursor \o \c size_fdiag
- \row \o \inlineimage cursor-wait.png
- \o Qt::WaitCursor \o \c wait
- \o \inlineimage cursor-sizeall.png
- \o Qt::SizeAllCursor \o \c size_all
- \row \o \inlineimage cursor-busy.png
- \o Qt::BusyCursor \o \c left_ptr_watch
- \o \inlineimage cursor-vsplit.png
- \o Qt::SplitVCursor \o \c split_v
- \row \o \inlineimage cursor-forbidden.png
- \o Qt::ForbiddenCursor \o \c forbidden
- \o \inlineimage cursor-hsplit.png
- \o Qt::SplitHCursor \o \c split_h
- \row \o \inlineimage cursor-hand.png
- \o Qt::PointingHandCursor \o \c pointing_hand
- \o \inlineimage cursor-openhand.png
- \o Qt::OpenHandCursor \o \c openhand
- \row \o \inlineimage cursor-whatsthis.png
- \o Qt::WhatsThisCursor \o \c whats_this
- \o \inlineimage cursor-closedhand.png
- \o Qt::ClosedHandCursor \o \c closedhand
- \row \o
- \o Qt::DragMoveCursor \o \c dnd-move or \c move
- \o
- \o Qt::DragCopyCursor \o \c dnd-copy or \c copy
- \row \o
- \o Qt::DragLinkCursor \o \c dnd-link or \c link
+ \header \li Shape \li Qt::CursorShape Value \li Cursor Name
+ \li Shape \li Qt::CursorShape Value \li Cursor Name
+ \row \li \inlineimage cursor-arrow.png
+ \li Qt::ArrowCursor \li \c left_ptr
+ \li \inlineimage cursor-sizev.png
+ \li Qt::SizeVerCursor \li \c size_ver
+ \row \li \inlineimage cursor-uparrow.png
+ \li Qt::UpArrowCursor \li \c up_arrow
+ \li \inlineimage cursor-sizeh.png
+ \li Qt::SizeHorCursor \li \c size_hor
+ \row \li \inlineimage cursor-cross.png
+ \li Qt::CrossCursor \li \c cross
+ \li \inlineimage cursor-sizeb.png
+ \li Qt::SizeBDiagCursor \li \c size_bdiag
+ \row \li \inlineimage cursor-ibeam.png
+ \li Qt::IBeamCursor \li \c ibeam
+ \li \inlineimage cursor-sizef.png
+ \li Qt::SizeFDiagCursor \li \c size_fdiag
+ \row \li \inlineimage cursor-wait.png
+ \li Qt::WaitCursor \li \c wait
+ \li \inlineimage cursor-sizeall.png
+ \li Qt::SizeAllCursor \li \c size_all
+ \row \li \inlineimage cursor-busy.png
+ \li Qt::BusyCursor \li \c left_ptr_watch
+ \li \inlineimage cursor-vsplit.png
+ \li Qt::SplitVCursor \li \c split_v
+ \row \li \inlineimage cursor-forbidden.png
+ \li Qt::ForbiddenCursor \li \c forbidden
+ \li \inlineimage cursor-hsplit.png
+ \li Qt::SplitHCursor \li \c split_h
+ \row \li \inlineimage cursor-hand.png
+ \li Qt::PointingHandCursor \li \c pointing_hand
+ \li \inlineimage cursor-openhand.png
+ \li Qt::OpenHandCursor \li \c openhand
+ \row \li \inlineimage cursor-whatsthis.png
+ \li Qt::WhatsThisCursor \li \c whats_this
+ \li \inlineimage cursor-closedhand.png
+ \li Qt::ClosedHandCursor \li \c closedhand
+ \row \li
+ \li Qt::DragMoveCursor \li \c dnd-move or \c move
+ \li
+ \li Qt::DragCopyCursor \li \c dnd-copy or \c copy
+ \row \li
+ \li Qt::DragLinkCursor \li \c dnd-link or \c link
\endtable
\sa QWidget, {fowler}{GUI Design Handbook: Cursors}
@@ -346,10 +346,10 @@ QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
The cursor \a bitmap (B) and \a mask (M) bits are combined like this:
\list
- \o B=1 and M=1 gives black.
- \o B=0 and M=1 gives white.
- \o B=0 and M=0 gives transparent.
- \o B=1 and M=0 gives an XOR'd result under Windows, undefined
+ \li B=1 and M=1 gives black.
+ \li B=0 and M=1 gives white.
+ \li B=0 and M=0 gives transparent.
+ \li B=1 and M=0 gives an XOR'd result under Windows, undefined
results on all other platforms.
\endlist
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index 2fb250cf18..1ed4a96192 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -125,417 +125,79 @@ QString KeyboardModifiersToString(Qt::KeyboardModifiers moderfies)
#endif
// the universe's only drag manager
-QDragManager *QDragManager::instance = 0;
+QDragManager *QDragManager::m_instance = 0;
QDragManager::QDragManager()
- : QObject(qApp)
+ : QObject(qApp), m_platformDropData(0), m_currentDropTarget(0),
+ m_platformDrag(QGuiApplicationPrivate::platformIntegration()->drag()),
+ m_object(0)
{
- Q_ASSERT(!instance);
+ Q_ASSERT(!m_instance);
- object = 0;
- beingCancelled = false;
- restoreCursor = false;
- willDrop = false;
- eventLoop = 0;
- currentDropTarget = 0;
- shapedPixmapWindow = 0;
-
- possible_actions = Qt::IgnoreAction;
-
- QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
- platformDrag = pi->drag();
-
- platformDropData = 0;
- if (platformDrag)
- platformDropData = platformDrag->platformDropData();
+ if (m_platformDrag)
+ m_platformDropData = m_platformDrag->platformDropData();
}
QDragManager::~QDragManager()
{
-#ifndef QT_NO_CURSOR
- if (restoreCursor)
- QGuiApplication::restoreOverrideCursor();
-#endif
- instance = 0;
+ m_instance = 0;
}
QDragManager *QDragManager::self()
{
- if (!instance && !QGuiApplication::closingDown())
- instance = new QDragManager;
- return instance;
+ if (!m_instance && !QGuiApplication::closingDown())
+ m_instance = new QDragManager;
+ return m_instance;
}
-QPixmap QDragManager::dragCursor(Qt::DropAction action) const
+QObject *QDragManager::source() const
{
- typedef QMap<Qt::DropAction, QPixmap>::const_iterator Iterator;
-
- if (const QDragPrivate *d = dragPrivate()) {
- const Iterator it = d->customCursors.constFind(action);
- if (it != d->customCursors.constEnd())
- return it.value();
- }
-
- Qt::CursorShape shape = Qt::ForbiddenCursor;
- switch (action) {
- case Qt::MoveAction:
- shape = Qt::DragMoveCursor;
- break;
- case Qt::CopyAction:
- shape = Qt::DragCopyCursor;
- break;
- case Qt::LinkAction:
- shape = Qt::DragLinkCursor;
- break;
- default:
- shape = Qt::ForbiddenCursor;
- }
- return QGuiApplicationPrivate::instance()->getPixmapCursor(shape);
-}
-
-Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
- Qt::KeyboardModifiers modifiers) const
-{
-#ifdef QDND_DEBUG
- qDebug("QDragManager::defaultAction(Qt::DropActions possibleActions)");
- qDebug("keyboard modifiers : %s", KeyboardModifiersToString(modifiers).latin1());
-#endif
-
- QDragPrivate *d = dragPrivate();
- Qt::DropAction defaultAction = d ? d->defaultDropAction : Qt::IgnoreAction;
-
- if (defaultAction == Qt::IgnoreAction) {
- //This means that the drag was initiated by QDrag::start and we need to
- //preserve the old behavior
- defaultAction = Qt::CopyAction;
- }
-
- if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier)
- defaultAction = Qt::LinkAction;
- else if (modifiers & Qt::ControlModifier)
- defaultAction = Qt::CopyAction;
- else if (modifiers & Qt::ShiftModifier)
- defaultAction = Qt::MoveAction;
- else if (modifiers & Qt::AltModifier)
- defaultAction = Qt::LinkAction;
-
-#ifdef QDND_DEBUG
- qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
-#endif
-
- // Check if the action determined is allowed
- if (!(possibleActions & defaultAction)) {
- if (possibleActions & Qt::CopyAction)
- defaultAction = Qt::CopyAction;
- else if (possibleActions & Qt::MoveAction)
- defaultAction = Qt::MoveAction;
- else if (possibleActions & Qt::LinkAction)
- defaultAction = Qt::LinkAction;
- else
- defaultAction = Qt::IgnoreAction;
- }
-
-#ifdef QDND_DEBUG
- qDebug("default action : %s", dragActionsToString(defaultAction).latin1());
-#endif
-
- return defaultAction;
+ if (m_object)
+ return m_object->source();
+ return 0;
}
void QDragManager::setCurrentTarget(QObject *target, bool dropped)
{
- if (currentDropTarget == target)
+ if (m_currentDropTarget == target)
return;
- currentDropTarget = target;
- if (!dropped && object) {
- object->d_func()->target = target;
- emit object->targetChanged(target);
+ m_currentDropTarget = target;
+ if (!dropped && m_object) {
+ m_object->d_func()->target = target;
+ emit m_object->targetChanged(target);
}
-
}
-QObject *QDragManager::currentTarget()
+QObject *QDragManager::currentTarget() const
{
- return currentDropTarget;
-}
-
-
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char *const default_pm[] = {
-"13 9 3 1",
-". c None",
-" c #000000",
-"X c #FFFFFF",
-"X X X X X X X",
-" X X X X X X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X X X X X X ",
-"X X X X X X X",
-};
-
-
-QShapedPixmapWindow::QShapedPixmapWindow()
- : QWindow()
-{
- setSurfaceType(RasterSurface);
- setWindowFlags(Qt::Tool | Qt::FramelessWindowHint |
- Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput);
- create();
- backingStore = new QBackingStore(this);
-}
-
-void QShapedPixmapWindow::render()
-{
- QRect rect(QPoint(), geometry().size());
- backingStore->resize(rect.size());
-
- backingStore->beginPaint(rect);
-
- QPaintDevice *device = backingStore->paintDevice();
-
- {
- QPainter p(device);
- p.drawPixmap(0, 0, pixmap);
- }
-
- backingStore->endPaint();
- backingStore->flush(rect);
-}
-
-
-
-
-static Qt::KeyboardModifiers oldstate;
-
-void QDragManager::updatePixmap()
-{
- if (shapedPixmapWindow) {
- shapedPixmapWindow->pixmap = QPixmap();
- shapedPixmapWindow->hotSpot = QPoint(default_pm_hotx,default_pm_hoty);
- if (object) {
- shapedPixmapWindow->pixmap = object->pixmap();
- if (!shapedPixmapWindow->pixmap.isNull())
- shapedPixmapWindow->hotSpot = object->hotSpot();
- }
- if (shapedPixmapWindow->pixmap.isNull())
- shapedPixmapWindow->pixmap = QPixmap(default_pm);
- shapedPixmapWindow->setGeometry(QRect(QCursor::pos() - shapedPixmapWindow->hotSpot, shapedPixmapWindow->pixmap.size()));
- shapedPixmapWindow->show();
- shapedPixmapWindow->render();
- }
-}
-
-void QDragManager::updateCursor()
-{
- if (shapedPixmapWindow) {
- shapedPixmapWindow->render(); // ### Hack
- shapedPixmapWindow->move(QCursor::pos() - shapedPixmapWindow->hotSpot);
- }
-
- Qt::CursorShape cursorShape = Qt::ForbiddenCursor;
- if (willDrop) {
- if (global_accepted_action == Qt::CopyAction) {
- cursorShape = Qt::DragCopyCursor;
- } else if (global_accepted_action == Qt::LinkAction) {
- cursorShape = Qt::DragLinkCursor;
- } else {
- cursorShape = Qt::DragMoveCursor;
- }
- }
- QCursor *cursor = qApp->overrideCursor();
- if (cursor && cursorShape != cursor->shape())
- qApp->changeOverrideCursor(QCursor(cursorShape));
-}
-
-
-bool QDragManager::eventFilter(QObject *o, QEvent *e)
-{
- if (beingCancelled) {
- if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
- qApp->removeEventFilter(this);
- Q_ASSERT(object == 0);
- beingCancelled = false;
- eventLoop->exit();
- return true; // block the key release
- }
- return false;
- }
-
- Q_ASSERT(object != 0);
-
- if (!qobject_cast<QWindow *>(o))
- return false;
-
- switch(e->type()) {
- case QEvent::ShortcutOverride:
- // prevent accelerators from firing while dragging
- e->accept();
- return true;
-
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
- if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- eventLoop->exit();
- } else {
- // ### x11 forces move!
- updateCursor();
- }
- return true; // Eat all key events
- }
-
- case QEvent::MouseMove:
- move(static_cast<QMouseEvent *>(e));
- return true; // Eat all mouse events
-
- case QEvent::MouseButtonRelease:
- qApp->removeEventFilter(this);
- if (willDrop)
- drop(static_cast<QMouseEvent *>(e));
- else
- cancel();
- beingCancelled = false;
- eventLoop->exit();
- return true; // Eat all mouse events
-
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- case QEvent::Wheel:
- return true;
- default:
- break;
- }
- return false;
+ return m_currentDropTarget;
}
Qt::DropAction QDragManager::drag(QDrag *o)
{
- if (!o || object == o)
+ if (!o || m_object == o)
return Qt::IgnoreAction;
- if (!platformDrag || !o->source()) {
+ if (!m_platformDrag || !o->source()) {
o->deleteLater();
return Qt::IgnoreAction;
}
- if (object) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- }
-
- object = o;
- if (!shapedPixmapWindow)
- shapedPixmapWindow = new QShapedPixmapWindow();
- oldstate = Qt::NoModifier; // #### Should use state that caused the drag
-// drag_mode = mode;
-
- possible_actions = dragPrivate()->possible_actions;
-
- willDrop = false;
- object->d_func()->target = 0;
- qApp->installEventFilter(this);
-
- global_accepted_action = Qt::CopyAction;
-#ifndef QT_NO_CURSOR
- qApp->setOverrideCursor(Qt::DragCopyCursor);
- restoreCursor = true;
- updateCursor();
-#endif
- updatePixmap();
-
- platformDrag->startDrag();
-
- eventLoop = new QEventLoop;
- (void) eventLoop->exec();
- delete eventLoop;
- eventLoop = 0;
-
- delete shapedPixmapWindow;
- shapedPixmapWindow = 0;
-
- return global_accepted_action;
-}
-
-void QDragManager::move(const QMouseEvent *me)
-{
- if (!platformDrag)
- return;
-
- platformDrag->move(me);
-}
-
-void QDragManager::drop(const QMouseEvent *me)
-{
- if (!platformDrag)
- return;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QGuiApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
- willDrop = false;
-
- platformDrag->drop(me);
-
- if (object)
- object->deleteLater();
- object = 0;
-}
-
-void QDragManager::cancel(bool deleteSource)
-{
- if (!platformDrag)
- return;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QGuiApplication::restoreOverrideCursor();
- restoreCursor = false;
+ if (m_object) {
+ qWarning("QDragManager::drag in possibly invalid state");
+ return Qt::IgnoreAction;
}
-#endif
-
- beingCancelled = true;
- platformDrag->cancel();
+ m_object = o;
- if (object && deleteSource)
- object->deleteLater();
- object = 0;
+ m_object->d_func()->target = 0;
- global_accepted_action = Qt::IgnoreAction;
-}
-
-/*!
- Called from startDrag() in QPlatformDrag implementations that do not need
- the desktop-oriented stuff provided by the event filter (e.g. because their
- drag is not based on mouse events). Instead, they will manage everything on
- their own, will not rely on move/drop/cancel, and will call stopDrag() to stop
- the event loop when the drag is over.
- */
-void QDragManager::unmanageEvents()
-{
- qApp->removeEventFilter(this);
-}
-
-void QDragManager::stopDrag()
-{
- if (eventLoop)
- eventLoop->exit();
+ const Qt::DropAction result = m_platformDrag->drag(m_object);
+ m_object = 0;
+ return result;
}
#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 857be34d10..764b73c06f 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -98,100 +98,45 @@ protected:
class QDragPrivate : public QObjectPrivate
{
public:
+ QDragPrivate()
+ : source(0)
+ , target(0)
+ , data(0)
+ { }
QObject *source;
QObject *target;
QMimeData *data;
QPixmap pixmap;
QPoint hotspot;
- Qt::DropActions possible_actions;
Qt::DropAction executed_action;
+ Qt::DropActions supported_actions;
+ Qt::DropAction default_action;
QMap<Qt::DropAction, QPixmap> customCursors;
- Qt::DropAction defaultDropAction;
};
-class QShapedPixmapWindow : public QWindow
-{
-public:
- QShapedPixmapWindow();
-
- void exposeEvent(QExposeEvent *)
- {
- render();
- }
-
- void render();
-
- QBackingStore *backingStore;
- QPixmap pixmap;
- QPoint hotSpot;
-};
-
-
class Q_GUI_EXPORT QDragManager : public QObject {
Q_OBJECT
- // only friend classes can use QDragManager.
- friend class QDrag;
- friend class QDragMoveEvent;
- friend class QDropEvent;
- friend class QApplication;
-
- bool eventFilter(QObject *, QEvent *);
-
public:
QDragManager();
~QDragManager();
static QDragManager *self();
- virtual Qt::DropAction drag(QDrag *);
-
- virtual void cancel(bool deleteSource = true);
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
-
- void updatePixmap();
- void updateCursor();
-
- Qt::DropAction defaultAction(Qt::DropActions possibleActions,
- Qt::KeyboardModifiers modifiers) const;
-
- QPixmap dragCursor(Qt::DropAction action) const;
-
- QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
-
- inline QMimeData *dropData()
- { return object ? dragPrivate()->data : platformDropData; }
-
- void emitActionChanged(Qt::DropAction newAction) { if (object) emit object->actionChanged(newAction); }
+ Qt::DropAction drag(QDrag *);
void setCurrentTarget(QObject *target, bool dropped = false);
- QObject *currentTarget();
+ QObject *currentTarget() const;
- QDrag *object;
-
- bool beingCancelled;
- bool restoreCursor;
- bool willDrop;
- QEventLoop *eventLoop;
-
- Qt::DropActions possible_actions;
- // Shift/Ctrl handling, and final drop status
- Qt::DropAction global_accepted_action;
-
- QShapedPixmapWindow *shapedPixmapWindow;
-
- void unmanageEvents();
- void stopDrag();
+ QDrag *object() const { return m_object; }
+ QObject *source() const;
private:
- QMimeData *platformDropData;
-
- Qt::DropAction currentActionForOverrideCursor;
- QObject *currentDropTarget;
-
- QPlatformDrag *platformDrag;
+ QMimeData *m_platformDropData;
+ QObject *m_currentDropTarget;
+ QPlatformDrag *m_platformDrag;
+ QDrag *m_object;
- static QDragManager *instance;
+ static QDragManager *m_instance;
Q_DISABLE_COPY(QDragManager)
};
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 694b12a180..40015c8706 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <qdrag.h>
+#include "private/qguiapplication_p.h"
#include <qpixmap.h>
#include <qpoint.h>
#include "qdnd_p.h"
@@ -114,9 +115,9 @@ QDrag::QDrag(QObject *dragSource)
d->target = 0;
d->data = 0;
d->hotspot = QPoint(-10, -10);
- d->possible_actions = Qt::CopyAction;
d->executed_action = Qt::IgnoreAction;
- d->defaultDropAction = Qt::IgnoreAction;
+ d->supported_actions = Qt::IgnoreAction;
+ d->default_action = Qt::IgnoreAction;
}
/*!
@@ -126,9 +127,6 @@ QDrag::~QDrag()
{
Q_D(QDrag);
delete d->data;
- QDragManager *manager = QDragManager::self();
- if (manager && manager->object == this)
- manager->cancel(false);
}
/*!
@@ -178,7 +176,7 @@ QPixmap QDrag::pixmap() const
Sets the position of the hot spot relative to the top-left corner of the
pixmap used to the point specified by \a hotspot.
- \bold{Note:} on X11, the pixmap may not be able to keep up with the mouse
+ \b{Note:} on X11, the pixmap may not be able to keep up with the mouse
movements if the hot spot causes the pixmap to be displayed
directly under the cursor.
*/
@@ -226,7 +224,7 @@ QObject *QDrag::target() const
from are specified in \a supportedActions. The default proposed action will be selected
among the allowed actions in the following order: Move, Copy and Link.
- \bold{Note:} On Linux and Mac OS X, the drag and drop operation
+ \b{Note:} On Linux and Mac OS X, the drag and drop operation
can take some time, but this function does not block the event
loop. Other events are still delivered to the application while
the operation is performed. On Windows, the Qt event loop is
@@ -248,7 +246,7 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
The \a defaultDropAction determines which action will be proposed when the user performs a
drag without using modifier keys.
- \bold{Note:} On Linux and Mac OS X, the drag and drop operation
+ \b{Note:} On Linux and Mac OS X, the drag and drop operation
can take some time, but this function does not block the event
loop. Other events are still delivered to the application while
the operation is performed. On Windows, the Qt event loop is
@@ -264,24 +262,22 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa
qWarning("QDrag: No mimedata set before starting the drag");
return d->executed_action;
}
- QDragManager *manager = QDragManager::self();
- d->defaultDropAction = Qt::IgnoreAction;
- d->possible_actions = supportedActions;
-
- if (manager) {
- if (defaultDropAction == Qt::IgnoreAction) {
- if (supportedActions & Qt::MoveAction) {
- d->defaultDropAction = Qt::MoveAction;
- } else if (supportedActions & Qt::CopyAction) {
- d->defaultDropAction = Qt::CopyAction;
- } else if (supportedActions & Qt::LinkAction) {
- d->defaultDropAction = Qt::LinkAction;
- }
- } else {
- d->defaultDropAction = defaultDropAction;
+ Qt::DropAction transformedDefaultDropAction = Qt::IgnoreAction;
+
+ if (defaultDropAction == Qt::IgnoreAction) {
+ if (supportedActions & Qt::MoveAction) {
+ transformedDefaultDropAction = Qt::MoveAction;
+ } else if (supportedActions & Qt::CopyAction) {
+ transformedDefaultDropAction = Qt::CopyAction;
+ } else if (supportedActions & Qt::LinkAction) {
+ transformedDefaultDropAction = Qt::LinkAction;
}
- d->executed_action = manager->drag(this);
+ } else {
+ transformedDefaultDropAction = defaultDropAction;
}
+ d->supported_actions = supportedActions;
+ d->default_action = transformedDefaultDropAction;
+ d->executed_action = QDragManager::self()->drag(this);
return d->executed_action;
}
@@ -289,13 +285,13 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa
/*!
\obsolete
- \bold{Note:} It is recommended to use exec() instead of this function.
+ \b{Note:} It is recommended to use exec() instead of this function.
Starts the drag and drop operation and returns a value indicating the requested
drop action when it is completed. The drop actions that the user can choose
from are specified in \a request. Qt::CopyAction is always allowed.
- \bold{Note:} Although the drag and drop operation can take some time, this function
+ \b{Note:} Although the drag and drop operation can take some time, this function
does not block the event loop. Other events are still delivered to the application
while the operation is performed.
@@ -308,11 +304,9 @@ Qt::DropAction QDrag::start(Qt::DropActions request)
qWarning("QDrag: No mimedata set before starting the drag");
return d->executed_action;
}
- QDragManager *manager = QDragManager::self();
- d->defaultDropAction = Qt::IgnoreAction;
- d->possible_actions = request | Qt::CopyAction;
- if (manager)
- d->executed_action = manager->drag(this);
+ d->supported_actions = request | Qt::CopyAction;
+ d->default_action = Qt::IgnoreAction;
+ d->executed_action = QDragManager::self()->drag(this);
return d->executed_action;
}
@@ -336,6 +330,49 @@ void QDrag::setDragCursor(const QPixmap &cursor, Qt::DropAction action)
}
/*!
+ Returns the drag cursor for the \a action.
+
+ \since 5.0
+*/
+
+QPixmap QDrag::dragCursor(Qt::DropAction action) const
+{
+ typedef QMap<Qt::DropAction, QPixmap>::const_iterator Iterator;
+
+ Q_D(const QDrag);
+ const Iterator it = d->customCursors.constFind(action);
+ if (it != d->customCursors.constEnd())
+ return it.value();
+
+ Qt::CursorShape shape = Qt::ForbiddenCursor;
+ switch (action) {
+ case Qt::MoveAction:
+ shape = Qt::DragMoveCursor;
+ break;
+ case Qt::CopyAction:
+ shape = Qt::DragCopyCursor;
+ break;
+ case Qt::LinkAction:
+ shape = Qt::DragLinkCursor;
+ break;
+ default:
+ shape = Qt::ForbiddenCursor;
+ }
+ return QGuiApplicationPrivate::instance()->getPixmapCursor(shape);
+}
+
+Qt::DropActions QDrag::supportedActions() const
+{
+ Q_D(const QDrag);
+ return d->supported_actions;
+}
+
+Qt::DropAction QDrag::defaultAction() const
+{
+ Q_D(const QDrag);
+ return d->default_action;
+}
+/*!
\fn void QDrag::actionChanged(Qt::DropAction action)
This signal is emitted when the \a action associated with the
diff --git a/src/gui/kernel/qdrag.h b/src/gui/kernel/qdrag.h
index 0a1ddff2d9..de84b6588b 100644
--- a/src/gui/kernel/qdrag.h
+++ b/src/gui/kernel/qdrag.h
@@ -56,6 +56,7 @@ class QPixmap;
class QPoint;
class QDragManager;
+
class Q_GUI_EXPORT QDrag : public QObject
{
Q_OBJECT
@@ -81,6 +82,10 @@ public:
Qt::DropAction exec(Qt::DropActions supportedActions, Qt::DropAction defaultAction);
void setDragCursor(const QPixmap &cursor, Qt::DropAction action);
+ QPixmap dragCursor(Qt::DropAction action) const;
+
+ Qt::DropActions supportedActions() const;
+ Qt::DropAction defaultAction() const;
Q_SIGNALS:
void actionChanged(Qt::DropAction action);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 281d4f61bc..60e754b289 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -377,9 +377,9 @@ QMouseEvent::~QMouseEvent()
you will get the following QEvent::MouseMove events:
\list 1
- \o A::MouseMove
- \o B::MouseMove
- \o C::MouseMove
+ \li A::MouseMove
+ \li B::MouseMove
+ \li C::MouseMove
\endlist
You will get the same events for QEvent::HoverMove, except that the event
@@ -390,9 +390,9 @@ QMouseEvent::~QMouseEvent()
In this case the events will occur in the following way:
\list 1
- \o A::HoverMove
- \o A::HoverMove, B::HoverMove
- \o A::HoverMove, B::HoverMove, C::HoverMove
+ \li A::HoverMove
+ \li A::HoverMove, B::HoverMove
+ \li A::HoverMove, B::HoverMove, C::HoverMove
\endlist
*/
@@ -1483,20 +1483,20 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos)
step process:
\list 1
- \o \bold{Starting to Compose}
+ \li \b{Starting to Compose}
When the user presses the first key on a keyboard, an input
context is created. This input context will contain a string
of the typed characters.
- \o \bold{Composing}
+ \li \b{Composing}
With every new key pressed, the input method will try to create a
matching string for the text typed so far called preedit
string. While the input context is active, the user can only move
the cursor inside the string belonging to this input context.
- \o \bold{Completing}
+ \li \b{Completing}
At some point, the user will activate a user interface component
(perhaps using a particular key) where they can choose from a
@@ -1539,10 +1539,10 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos)
following steps:
\list 1
- \o If the widget has selected text, the selected text should get
+ \li If the widget has selected text, the selected text should get
removed.
- \o Remove the text starting at replacementStart() with length
+ \li Remove the text starting at replacementStart() with length
replacementLength() and replace it by the commitString(). If
replacementLength() is 0, replacementStart() gives the insertion
position for the commitString().
@@ -1556,7 +1556,7 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos)
If the widget implements undo/redo, this operation gets added to
the undo stack.
- \o If there is no current preedit string, insert the
+ \li If there is no current preedit string, insert the
preeditString() at the current cursor position; otherwise replace
the previous preeditString with the one received from this event.
@@ -2060,7 +2060,7 @@ QTabletEvent::~QTabletEvent()
Returns the z position of the device. Typically this is represented by a
wheel on a 4D Mouse. If the device does not support a Z-axis, this value is
- always zero. This is \bold not the same as pressure.
+ always zero. This is \b not the same as pressure.
\sa pressure()
*/
@@ -2295,8 +2295,9 @@ QDropEvent::~QDropEvent()
*/
QObject* QDropEvent::source() const
{
- QDragManager *manager = QDragManager::self();
- return (manager && manager->object) ? manager->object->source() : 0;
+ if (const QDragManager *manager = QDragManager::self())
+ return manager->source();
+ return 0;
}
@@ -2575,11 +2576,11 @@ QHelpEvent::~QHelpEvent()
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/qstatustipevent/main.cpp 1
\dots
\snippet doc/src/snippets/qstatustipevent/main.cpp 3
- \o
+ \li
\image qstatustipevent-widget.png Widget with status tip.
\endtable
@@ -2588,12 +2589,12 @@ QHelpEvent::~QHelpEvent()
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/qstatustipevent/main.cpp 0
\snippet doc/src/snippets/qstatustipevent/main.cpp 2
\dots
\snippet doc/src/snippets/qstatustipevent/main.cpp 3
- \o
+ \li
\image qstatustipevent-action.png Action with status tip.
\endtable
@@ -2998,7 +2999,9 @@ QDebug operator<<(QDebug dbg, const QEvent *e) {
break;
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
- dbg.nospace() << "QWheelEvent(" << static_cast<const QWheelEvent *>(e)->delta()
+ dbg.nospace() << "QWheelEvent("
+ << static_cast<const QWheelEvent *>(e)->pixelDelta()
+ << static_cast<const QWheelEvent *>(e)->angleDelta()
<< ')';
return dbg.space();
#endif
@@ -3402,10 +3405,10 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
\list
- \i When the first touch point is detected, the destination widget is determined firstly by the
+ \li When the first touch point is detected, the destination widget is determined firstly by the
location on screen and secondly by the propagation rules.
- \i When additional touch points are detected, Qt first looks to see if there are any active
+ \li When additional touch points are detected, Qt first looks to see if there are any active
touch points on any ancestor or descendent of the widget under the new touch point. If there
are, the new touch point is grouped with the first, and the new touch point will be sent in a
single QTouchEvent to the widget that handled the first touch point. (The widget under the new
@@ -3427,19 +3430,19 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
\list
- \i As mentioned above, enabling touch events means multiple widgets can be receiving touch
+ \li As mentioned above, enabling touch events means multiple widgets can be receiving touch
events simultaneously. Combined with the default QWidget::event() handling for QTouchEvents,
this gives you great flexibility in designing touch user interfaces. Be aware of the
implications. For example, it is possible that the user is moving a QSlider with one finger and
pressing a QPushButton with another. The signals emitted by these widgets will be
interleaved.
- \i Recursion into the event loop using one of the exec() methods (e.g., QDialog::exec() or
+ \li Recursion into the event loop using one of the exec() methods (e.g., QDialog::exec() or
QMenu::exec()) in a QTouchEvent event handler is not supported. Since there are multiple event
recipients, recursion may cause problems, including but not limited to lost events
and unexpected infinite recursion.
- \i QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an
+ \li QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an
\l{QApplication::activePopupWidget()}{active pop-up widget}. The behavior of QTouchEvents is
undefined when opening a pop-up or grabbing the mouse while there are more than one active touch
points.
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 1cd448a6bb..be82005a54 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -73,8 +73,11 @@
#include "private/qwindowsysteminterface_qpa_p.h"
#include "private/qwindow_p.h"
#include "private/qcursor_p.h"
+
#include "private/qdnd_p.h"
#include <private/qplatformthemefactory_qpa_p.h>
+#include "qplatformdrag_qpa.h"
+
#ifndef QT_NO_CURSOR
#include "qplatformcursor_qpa.h"
#endif
@@ -192,7 +195,7 @@ static inline void clearFontUnlocked()
application's initialization and finalization. In addition, QGuiApplication handles
most of the system-wide and application-wide settings.
- For any GUI application using Qt, there is precisely \bold one QGuiApplication
+ For any GUI application using Qt, there is precisely \b one QGuiApplication
object no matter whether the application has 0, 1, 2 or more windows at
any given time. For non-GUI Qt applications, use QCoreApplication instead,
as it does not depend on the \l QtGui library.
@@ -202,30 +205,30 @@ static inline void clearFontUnlocked()
QGuiApplication's main areas of responsibility are:
\list
- \o It initializes the application with the user's desktop settings,
+ \li It initializes the application with the user's desktop settings,
such as palette(), font() and styleHints(). It keeps
track of these properties in case the user changes the desktop
globally, for example, through some kind of control panel.
- \o It performs event handling, meaning that it receives events
+ \li It performs event handling, meaning that it receives events
from the underlying window system and dispatches them to the
relevant widgets. You can send your own events to windows by
using sendEvent() and postEvent().
- \o It parses common command line arguments and sets its internal
+ \li It parses common command line arguments and sets its internal
state accordingly. See the \l{QGuiApplication::QGuiApplication()}
{constructor documentation} below for more details.
- \o It provides localization of strings that are visible to the
+ \li It provides localization of strings that are visible to the
user via translate().
- \o It provides some magical objects like the clipboard().
+ \li It provides some magical objects like the clipboard().
- \o It knows about the application's windows. You can ask which
+ \li It knows about the application's windows. You can ask which
window is at a certain position using topLevelAt(), get a list of
topLevelWindows(), etc.
- \o It manages the application's mouse cursor handling, see
+ \li It manages the application's mouse cursor handling, see
setOverrideCursor()
\endlist
@@ -237,11 +240,11 @@ static inline void clearFontUnlocked()
\table
\header
- \o{2,1} Groups of functions
+ \li{2,1} Groups of functions
\row
- \o System settings
- \o desktopSettingsAware(),
+ \li System settings
+ \li desktopSettingsAware(),
setDesktopSettingsAware(),
styleHints(),
palette(),
@@ -250,8 +253,8 @@ static inline void clearFontUnlocked()
setFont().
\row
- \o Event handling
- \o exec(),
+ \li Event handling
+ \li exec(),
processEvents(),
exit(),
quit().
@@ -263,22 +266,22 @@ static inline void clearFontUnlocked()
notify().
\row
- \o Windows
- \o allWindows(),
+ \li Windows
+ \li allWindows(),
topLevelWindows(),
focusWindow(),
clipboard(),
topLevelAt().
\row
- \o Advanced cursor handling
- \o overrideCursor(),
+ \li Advanced cursor handling
+ \li overrideCursor(),
setOverrideCursor(),
restoreOverrideCursor().
\row
- \o Miscellaneous
- \o startingUp(),
+ \li Miscellaneous
+ \li startingUp(),
closingDown(),
type().
\endtable
@@ -306,9 +309,9 @@ static inline void clearFontUnlocked()
All Qt programs automatically support the following command line options:
\list
- \o -reverse, sets the application's layout direction to
+ \li -reverse, sets the application's layout direction to
Qt::RightToLeft
- \o -qmljsdebugger=, activates the QML/JS debugger with a specified port.
+ \li -qmljsdebugger=, activates the QML/JS debugger with a specified port.
The value must be of format port:1234[,block], where block is optional
and will make the application wait until a debugger connects to it.
\endlist
@@ -326,8 +329,7 @@ QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
: QCoreApplication(p)
{
- d_func()->init();
-}
+ d_func()->init(); }
/*!
Destructs the application.
@@ -1547,49 +1549,62 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
}
-Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
static QPointer<QWindow> currentDragWindow;
- QDragManager *manager = QDragManager::self();
+ static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
+ QPlatformDrag *platformDrag = platformIntegration()->drag();
+ if (!platformDrag) {
+ lastAcceptedDropAction = Qt::IgnoreAction;
+ return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
+ }
+
if (!dropData) {
if (currentDragWindow.data() == w)
currentDragWindow = 0;
QDragLeaveEvent e;
QGuiApplication::sendEvent(w, &e);
- manager->global_accepted_action = Qt::IgnoreAction;
- return Qt::IgnoreAction;
+ lastAcceptedDropAction = Qt::IgnoreAction;
+ return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
}
- QDragMoveEvent me(p, manager->possible_actions, dropData,
+ QDragMoveEvent me(p, supportedActions, dropData,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+
if (w != currentDragWindow) {
+ lastAcceptedDropAction = Qt::IgnoreAction;
if (currentDragWindow) {
QDragLeaveEvent e;
QGuiApplication::sendEvent(currentDragWindow, &e);
- manager->global_accepted_action = Qt::IgnoreAction;
}
currentDragWindow = w;
- QDragEnterEvent e(p, manager->possible_actions, dropData,
+ QDragEnterEvent e(p, supportedActions, dropData,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
QGuiApplication::sendEvent(w, &e);
- manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
- if (manager->global_accepted_action != Qt::IgnoreAction) {
- me.setDropAction(manager->global_accepted_action);
- me.accept();
- }
+ if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction)
+ lastAcceptedDropAction = e.dropAction();
+ }
+
+ // Handling 'DragEnter' should suffice for the application.
+ if (lastAcceptedDropAction != Qt::IgnoreAction
+ && (supportedActions & lastAcceptedDropAction)) {
+ me.setDropAction(lastAcceptedDropAction);
+ me.accept();
}
QGuiApplication::sendEvent(w, &me);
- manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
- return manager->global_accepted_action;
+ lastAcceptedDropAction = me.isAccepted() ?
+ me.dropAction() : Qt::IgnoreAction;
+ return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect());
}
-Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- QDragManager *manager = QDragManager::self();
- QDropEvent de(p, manager->possible_actions, dropData,
+ QDropEvent de(p, supportedActions, dropData,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
QGuiApplication::sendEvent(w, &de);
- manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
- return manager->global_accepted_action;
+
+ Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
+ QPlatformDropQtResponse response(de.isAccepted(),acceptedAction);
+ return response;
}
#ifndef QT_NO_CLIPBOARD
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 68546ce0cf..d9477a3e9e 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -53,6 +53,8 @@
#include "private/qwindowsysteminterface_qpa_p.h"
#include "private/qshortcutmap_p.h"
+#include "qplatformdrag_qpa.h"
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -121,8 +123,8 @@ public:
static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
- static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
- static Qt::DropAction processDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
+ static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
+ static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 7053f01196..153b2b5c2d 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -164,14 +164,14 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
three different ways:
\list
- \o For standard shortcuts, a \l{QKeySequence::StandardKey}{standard key}
+ \li For standard shortcuts, a \l{QKeySequence::StandardKey}{standard key}
can be used to request the platform-specific key sequence associated
with each shortcut.
- \o For custom shortcuts, human-readable strings such as "Ctrl+X" can
+ \li For custom shortcuts, human-readable strings such as "Ctrl+X" can
be used, and these can be translated into the appropriate shortcuts
for users of different languages. Translations are made in the
"QShortcut" context.
- \o For hard-coded shortcuts, integer key codes can be specified with
+ \li For hard-coded shortcuts, integer key codes can be specified with
a combination of values defined by the Qt::Key and Qt::Modifier enum
values. Each key code consists of a single Qt::Key value and zero or
more modifiers, such as Qt::SHIFT, Qt::CTRL, Qt::ALT and Qt::META.
@@ -206,7 +206,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
code point of the character; for example, 'A' gives the same key sequence
as Qt::Key_A.
- \bold{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control
+ \b{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control
and Qt::ControlModifier correspond to the \key Command keys on the
Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and
Qt::MetaModifier correspond to the \key Control keys. Developers on
@@ -225,72 +225,72 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
corresponds to the \key Control keys.
\table
- \header \i StandardKey \i Windows \i Mac OS X \i KDE \i GNOME
- \row \i HelpContents \i F1 \i Ctrl+? \i F1 \i F1
- \row \i WhatsThis \i Shift+F1 \i Shift+F1 \i Shift+F1 \i Shift+F1
- \row \i Open \i Ctrl+O \i Ctrl+O \i Ctrl+O \i Ctrl+O
- \row \i Close \i Ctrl+F4, Ctrl+W \i Ctrl+W, Ctrl+F4 \i Ctrl+W \i Ctrl+W
- \row \i Save \i Ctrl+S \i Ctrl+S \i Ctrl+S \i Ctrl+S
- \row \i Quit \i \i Ctrl+Q \i Qtrl+Q \i Qtrl+Q
- \row \i SaveAs \i \i Ctrl+Shift+S \i \i Ctrl+Shift+S
- \row \i New \i Ctrl+N \i Ctrl+N \i Ctrl+N \i Ctrl+N
- \row \i Delete \i Del \i Del, Meta+D \i Del, Ctrl+D \i Del, Ctrl+D
- \row \i Cut \i Ctrl+X, Shift+Del \i Ctrl+X \i Ctrl+X, F20, Shift+Del \i Ctrl+X, F20, Shift+Del
- \row \i Copy \i Ctrl+C, Ctrl+Ins \i Ctrl+C \i Ctrl+C, F16, Ctrl+Ins \i Ctrl+C, F16, Ctrl+Ins
- \row \i Paste \i Ctrl+V, Shift+Ins \i Ctrl+V \i Ctrl+V, F18, Shift+Ins \i Ctrl+V, F18, Shift+Ins
- \row \i Preferences \i \i Ctrl+, \i \i
- \row \i Undo \i Ctrl+Z, Alt+Backspace \i Ctrl+Z \i Ctrl+Z, F14 \i Ctrl+Z, F14
- \row \i Redo \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z \i Ctrl+Shift+Z \i Ctrl+Shift+Z
- \row \i Back \i Alt+Left, Backspace \i Ctrl+[ \i Alt+Left \i Alt+Left
- \row \i Forward \i Alt+Right, Shift+Backspace \i Ctrl+] \i Alt+Right \i Alt+Right
- \row \i Refresh \i F5 \i F5 \i F5 \i Ctrl+R, F5
- \row \i ZoomIn \i Ctrl+Plus \i Ctrl+Plus \i Ctrl+Plus \i Ctrl+Plus
- \row \i ZoomOut \i Ctrl+Minus \i Ctrl+Minus \i Ctrl+Minus \i Ctrl+Minus
- \row \i Print \i Ctrl+P \i Ctrl+P \i Ctrl+P \i Ctrl+P
- \row \i AddTab \i Ctrl+T \i Ctrl+T \i Ctrl+Shift+N, Ctrl+T \i Ctrl+T
- \row \i NextChild \i Ctrl+Tab, Forward, Ctrl+F6 \i Ctrl+}, Forward, Ctrl+Tab \i Ctrl+Tab, Forward, Ctrl+Comma \i Ctrl+Tab, Forward
- \row \i PreviousChild \i Ctrl+Shift+Tab, Back, Ctrl+Shift+F6 \i Ctrl+{, Back, Ctrl+Shift+Tab \i Ctrl+Shift+Tab, Back, Ctrl+Period \i Ctrl+Shift+Tab, Back
- \row \i Find \i Ctrl+F \i Ctrl+F \i Ctrl+F \i Ctrl+F
- \row \i FindNext \i F3, Ctrl+G \i Ctrl+G \i F3 \i Ctrl+G, F3
- \row \i FindPrevious \i Shift+F3, Ctrl+Shift+G \i Ctrl+Shift+G \i Shift+F3 \i Ctrl+Shift+G, Shift+F3
- \row \i Replace \i Ctrl+H \i (none) \i Ctrl+R \i Ctrl+H
- \row \i SelectAll \i Ctrl+A \i Ctrl+A \i Ctrl+A \i Ctrl+A
- \row \i Bold \i Ctrl+B \i Ctrl+B \i Ctrl+B \i Ctrl+B
- \row \i Italic \i Ctrl+I \i Ctrl+I \i Ctrl+I \i Ctrl+I
- \row \i Underline \i Ctrl+U \i Ctrl+U \i Ctrl+U \i Ctrl+U
- \row \i MoveToNextChar \i Right \i Right \i Right \i Right
- \row \i MoveToPreviousChar \i Left \i Left \i Left \i Left
- \row \i MoveToNextWord \i Ctrl+Right \i Alt+Right \i Ctrl+Right \i Ctrl+Right
- \row \i MoveToPreviousWord \i Ctrl+Left \i Alt+Left \i Ctrl+Left \i Ctrl+Left
- \row \i MoveToNextLine \i Down \i Down \i Down \i Down
- \row \i MoveToPreviousLine \i Up \i Up \i Up \i Up
- \row \i MoveToNextPage \i PgDown \i PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\i PgDown \i PgDown
- \row \i MoveToPreviousPage \i PgUp \i PgUp, Alt+PgUp, Meta+Up, Meta+PgUp \i PgUp \i PgUp
- \row \i MoveToStartOfLine \i Home \i Ctrl+Left, Meta+Left \i Home \i Home
- \row \i MoveToEndOfLine \i End \i Ctrl+Right, Meta+Right \i End \i End
- \row \i MoveToStartOfBlock \i (none) \i Alt+Up, Meta+A \i (none) \i (none)
- \row \i MoveToEndOfBlock \i (none) \i Alt+Down, Meta+E \i (none) \i (none)
- \row \i MoveToStartOfDocument\i Ctrl+Home \i Ctrl+Up, Home \i Ctrl+Home \i Ctrl+Home
- \row \i MoveToEndOfDocument \i Ctrl+End \i Ctrl+Down, End \i Ctrl+End \i Ctrl+End
- \row \i SelectNextChar \i Shift+Right \i Shift+Right \i Shift+Right \i Shift+Right
- \row \i SelectPreviousChar \i Shift+Left \i Shift+Left \i Shift+Left \i Shift+Left
- \row \i SelectNextWord \i Ctrl+Shift+Right \i Alt+Shift+Right \i Ctrl+Shift+Right \i Ctrl+Shift+Right
- \row \i SelectPreviousWord \i Ctrl+Shift+Left \i Alt+Shift+Left \i Ctrl+Shift+Left \i Ctrl+Shift+Left
- \row \i SelectNextLine \i Shift+Down \i Shift+Down \i Shift+Down \i Shift+Down
- \row \i SelectPreviousLine \i Shift+Up \i Shift+Up \i Shift+Up \i Shift+Up
- \row \i SelectNextPage \i Shift+PgDown \i Shift+PgDown \i Shift+PgDown \i Shift+PgDown
- \row \i SelectPreviousPage \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp
- \row \i SelectStartOfLine \i Shift+Home \i Ctrl+Shift+Left \i Shift+Home \i Shift+Home
- \row \i SelectEndOfLine \i Shift+End \i Ctrl+Shift+Right \i Shift+End \i Shift+End
- \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up, Meta+Shift+A \i (none) \i (none)
- \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down, Meta+Shift+E \i (none) \i (none)
- \row \i SelectStartOfDocument\i Ctrl+Shift+Home \i Ctrl+Shift+Up, Shift+Home \i Ctrl+Shift+Home\i Ctrl+Shift+Home
- \row \i SelectEndOfDocument \i Ctrl+Shift+End \i Ctrl+Shift+Down, Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End
- \row \i DeleteStartOfWord \i Ctrl+Backspace \i Alt+Backspace \i Ctrl+Backspace \i Ctrl+Backspace
- \row \i DeleteEndOfWord \i Ctrl+Del \i (none) \i Ctrl+Del \i Ctrl+Del
- \row \i DeleteEndOfLine \i (none) \i (none) \i Ctrl+K \i Ctrl+K
- \row \i InsertParagraphSeparator \i Enter \i Enter \i Enter \i Enter
- \row \i InsertLineSeparator \i Shift+Enter \i Meta+Enter \i Shift+Enter \i Shift+Enter
+ \header \li StandardKey \li Windows \li Mac OS X \li KDE \li GNOME
+ \row \li HelpContents \li F1 \li Ctrl+? \li F1 \li F1
+ \row \li WhatsThis \li Shift+F1 \li Shift+F1 \li Shift+F1 \li Shift+F1
+ \row \li Open \li Ctrl+O \li Ctrl+O \li Ctrl+O \li Ctrl+O
+ \row \li Close \li Ctrl+F4, Ctrl+W \li Ctrl+W, Ctrl+F4 \li Ctrl+W \li Ctrl+W
+ \row \li Save \li Ctrl+S \li Ctrl+S \li Ctrl+S \li Ctrl+S
+ \row \li Quit \li \li Ctrl+Q \li Qtrl+Q \li Qtrl+Q
+ \row \li SaveAs \li \li Ctrl+Shift+S \li \li Ctrl+Shift+S
+ \row \li New \li Ctrl+N \li Ctrl+N \li Ctrl+N \li Ctrl+N
+ \row \li Delete \li Del \li Del, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D
+ \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del
+ \row \li Copy \li Ctrl+C, Ctrl+Ins \li Ctrl+C \li Ctrl+C, F16, Ctrl+Ins \li Ctrl+C, F16, Ctrl+Ins
+ \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins
+ \row \li Preferences \li \li Ctrl+, \li \li
+ \row \li Undo \li Ctrl+Z, Alt+Backspace \li Ctrl+Z \li Ctrl+Z, F14 \li Ctrl+Z, F14
+ \row \li Redo \li Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \li Ctrl+Shift+Z \li Ctrl+Shift+Z \li Ctrl+Shift+Z
+ \row \li Back \li Alt+Left, Backspace \li Ctrl+[ \li Alt+Left \li Alt+Left
+ \row \li Forward \li Alt+Right, Shift+Backspace \li Ctrl+] \li Alt+Right \li Alt+Right
+ \row \li Refresh \li F5 \li F5 \li F5 \li Ctrl+R, F5
+ \row \li ZoomIn \li Ctrl+Plus \li Ctrl+Plus \li Ctrl+Plus \li Ctrl+Plus
+ \row \li ZoomOut \li Ctrl+Minus \li Ctrl+Minus \li Ctrl+Minus \li Ctrl+Minus
+ \row \li Print \li Ctrl+P \li Ctrl+P \li Ctrl+P \li Ctrl+P
+ \row \li AddTab \li Ctrl+T \li Ctrl+T \li Ctrl+Shift+N, Ctrl+T \li Ctrl+T
+ \row \li NextChild \li Ctrl+Tab, Forward, Ctrl+F6 \li Ctrl+}, Forward, Ctrl+Tab \li Ctrl+Tab, Forward, Ctrl+Comma \li Ctrl+Tab, Forward
+ \row \li PreviousChild \li Ctrl+Shift+Tab, Back, Ctrl+Shift+F6 \li Ctrl+{, Back, Ctrl+Shift+Tab \li Ctrl+Shift+Tab, Back, Ctrl+Period \li Ctrl+Shift+Tab, Back
+ \row \li Find \li Ctrl+F \li Ctrl+F \li Ctrl+F \li Ctrl+F
+ \row \li FindNext \li F3, Ctrl+G \li Ctrl+G \li F3 \li Ctrl+G, F3
+ \row \li FindPrevious \li Shift+F3, Ctrl+Shift+G \li Ctrl+Shift+G \li Shift+F3 \li Ctrl+Shift+G, Shift+F3
+ \row \li Replace \li Ctrl+H \li (none) \li Ctrl+R \li Ctrl+H
+ \row \li SelectAll \li Ctrl+A \li Ctrl+A \li Ctrl+A \li Ctrl+A
+ \row \li Bold \li Ctrl+B \li Ctrl+B \li Ctrl+B \li Ctrl+B
+ \row \li Italic \li Ctrl+I \li Ctrl+I \li Ctrl+I \li Ctrl+I
+ \row \li Underline \li Ctrl+U \li Ctrl+U \li Ctrl+U \li Ctrl+U
+ \row \li MoveToNextChar \li Right \li Right \li Right \li Right
+ \row \li MoveToPreviousChar \li Left \li Left \li Left \li Left
+ \row \li MoveToNextWord \li Ctrl+Right \li Alt+Right \li Ctrl+Right \li Ctrl+Right
+ \row \li MoveToPreviousWord \li Ctrl+Left \li Alt+Left \li Ctrl+Left \li Ctrl+Left
+ \row \li MoveToNextLine \li Down \li Down \li Down \li Down
+ \row \li MoveToPreviousLine \li Up \li Up \li Up \li Up
+ \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\li PgDown \li PgDown
+ \row \li MoveToPreviousPage \li PgUp \li PgUp, Alt+PgUp, Meta+Up, Meta+PgUp \li PgUp \li PgUp
+ \row \li MoveToStartOfLine \li Home \li Ctrl+Left, Meta+Left \li Home \li Home
+ \row \li MoveToEndOfLine \li End \li Ctrl+Right, Meta+Right \li End \li End
+ \row \li MoveToStartOfBlock \li (none) \li Alt+Up, Meta+A \li (none) \li (none)
+ \row \li MoveToEndOfBlock \li (none) \li Alt+Down, Meta+E \li (none) \li (none)
+ \row \li MoveToStartOfDocument\li Ctrl+Home \li Ctrl+Up, Home \li Ctrl+Home \li Ctrl+Home
+ \row \li MoveToEndOfDocument \li Ctrl+End \li Ctrl+Down, End \li Ctrl+End \li Ctrl+End
+ \row \li SelectNextChar \li Shift+Right \li Shift+Right \li Shift+Right \li Shift+Right
+ \row \li SelectPreviousChar \li Shift+Left \li Shift+Left \li Shift+Left \li Shift+Left
+ \row \li SelectNextWord \li Ctrl+Shift+Right \li Alt+Shift+Right \li Ctrl+Shift+Right \li Ctrl+Shift+Right
+ \row \li SelectPreviousWord \li Ctrl+Shift+Left \li Alt+Shift+Left \li Ctrl+Shift+Left \li Ctrl+Shift+Left
+ \row \li SelectNextLine \li Shift+Down \li Shift+Down \li Shift+Down \li Shift+Down
+ \row \li SelectPreviousLine \li Shift+Up \li Shift+Up \li Shift+Up \li Shift+Up
+ \row \li SelectNextPage \li Shift+PgDown \li Shift+PgDown \li Shift+PgDown \li Shift+PgDown
+ \row \li SelectPreviousPage \li Shift+PgUp \li Shift+PgUp \li Shift+PgUp \li Shift+PgUp
+ \row \li SelectStartOfLine \li Shift+Home \li Ctrl+Shift+Left \li Shift+Home \li Shift+Home
+ \row \li SelectEndOfLine \li Shift+End \li Ctrl+Shift+Right \li Shift+End \li Shift+End
+ \row \li SelectStartOfBlock \li (none) \li Alt+Shift+Up, Meta+Shift+A \li (none) \li (none)
+ \row \li SelectEndOfBlock \li (none) \li Alt+Shift+Down, Meta+Shift+E \li (none) \li (none)
+ \row \li SelectStartOfDocument\li Ctrl+Shift+Home \li Ctrl+Shift+Up, Shift+Home \li Ctrl+Shift+Home\li Ctrl+Shift+Home
+ \row \li SelectEndOfDocument \li Ctrl+Shift+End \li Ctrl+Shift+Down, Shift+End \li Ctrl+Shift+End \li Ctrl+Shift+End
+ \row \li DeleteStartOfWord \li Ctrl+Backspace \li Alt+Backspace \li Ctrl+Backspace \li Ctrl+Backspace
+ \row \li DeleteEndOfWord \li Ctrl+Del \li (none) \li Ctrl+Del \li Ctrl+Del
+ \row \li DeleteEndOfLine \li (none) \li (none) \li Ctrl+K \li Ctrl+K
+ \row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
+ \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter \li Shift+Enter \li Shift+Enter
\endtable
Note that, since the key sequences used for the standard shortcuts differ
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 90d96674bc..9a2eb12e3f 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -342,9 +342,9 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
The color groups:
\list
- \i The Active group is used for the window that has keyboard focus.
- \i The Inactive group is used for other windows.
- \i The Disabled group is used for widgets (not windows) that are
+ \li The Active group is used for the window that has keyboard focus.
+ \li The Inactive group is used for other windows.
+ \li The Disabled group is used for widgets (not windows) that are
disabled for some reason.
\endlist
diff --git a/src/gui/kernel/qplatformdrag_qpa.cpp b/src/gui/kernel/qplatformdrag_qpa.cpp
new file mode 100644
index 0000000000..832b91db7e
--- /dev/null
+++ b/src/gui/kernel/qplatformdrag_qpa.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdrag_qpa.h"
+
+#include <QtGui/private/qdnd_p.h>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QEventLoop>
+
+QT_BEGIN_NAMESPACE
+
+QPlatformDropQtResponse::QPlatformDropQtResponse(bool accepted, Qt::DropAction acceptedAction)
+ : m_accepted(accepted)
+ , m_accepted_action(acceptedAction)
+{
+}
+
+bool QPlatformDropQtResponse::isAccepted() const
+{
+ return m_accepted;
+}
+
+Qt::DropAction QPlatformDropQtResponse::acceptedAction() const
+{
+ return m_accepted_action;
+}
+
+QPlatformDragQtResponse::QPlatformDragQtResponse(bool accepted, Qt::DropAction acceptedAction, QRect answerRect)
+ : QPlatformDropQtResponse(accepted,acceptedAction)
+ , m_answer_rect(answerRect)
+{
+}
+
+QRect QPlatformDragQtResponse::answerRect() const
+{
+ return m_answer_rect;
+}
+
+class QPlatformDragPrivate {
+public:
+ QPlatformDragPrivate() : cursor_drop_action(Qt::IgnoreAction) {}
+
+ Qt::DropAction cursor_drop_action;
+};
+
+QPlatformDrag::QPlatformDrag() : d_ptr(new QPlatformDragPrivate)
+{
+}
+
+QPlatformDrag::~QPlatformDrag()
+{
+}
+
+QDrag *QPlatformDrag::currentDrag() const
+{
+ return QDragManager::self()->object();
+}
+
+Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions,
+ Qt::KeyboardModifiers modifiers) const
+{
+#ifdef QDND_DEBUG
+ qDebug("QDragManager::defaultAction(Qt::DropActions possibleActions)");
+ qDebug("keyboard modifiers : %s", KeyboardModifiersToString(modifiers).latin1());
+#endif
+
+ Qt::DropAction default_action = Qt::IgnoreAction;
+
+ if (currentDrag()) {
+ default_action = currentDrag()->defaultAction();
+ }
+
+
+ if (default_action == Qt::IgnoreAction) {
+ //This means that the drag was initiated by QDrag::start and we need to
+ //preserve the old behavior
+ default_action = Qt::CopyAction;
+ }
+
+ if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier)
+ default_action = Qt::LinkAction;
+ else if (modifiers & Qt::ControlModifier)
+ default_action = Qt::CopyAction;
+ else if (modifiers & Qt::ShiftModifier)
+ default_action = Qt::MoveAction;
+ else if (modifiers & Qt::AltModifier)
+ default_action = Qt::LinkAction;
+
+#ifdef QDND_DEBUG
+ qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
+#endif
+
+ // Check if the action determined is allowed
+ if (!(possibleActions & default_action)) {
+ if (possibleActions & Qt::CopyAction)
+ default_action = Qt::CopyAction;
+ else if (possibleActions & Qt::MoveAction)
+ default_action = Qt::MoveAction;
+ else if (possibleActions & Qt::LinkAction)
+ default_action = Qt::LinkAction;
+ else
+ default_action = Qt::IgnoreAction;
+ }
+
+#ifdef QDND_DEBUG
+ qDebug("default action : %s", dragActionsToString(defaultAction).latin1());
+#endif
+
+ return default_action;
+}
+
+/*!
+ \brief Called to notify QDrag about changes of the current action.
+ */
+
+void QPlatformDrag::updateAction(Qt::DropAction action)
+{
+ Q_D(QPlatformDrag);
+ if (d->cursor_drop_action != action) {
+ d->cursor_drop_action = action;
+ emit currentDrag()->actionChanged(action);
+ }
+}
+
+static const char *const default_pm[] = {
+"13 9 3 1",
+". c None",
+" c #000000",
+"X c #FFFFFF",
+"X X X X X X X",
+" X X X X X X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X X X X X X ",
+"X X X X X X X",
+};
+
+Q_GLOBAL_STATIC_WITH_ARGS(QPixmap,qt_drag_default_pixmap,(default_pm))
+
+QPixmap QPlatformDrag::defaultPixmap()
+{
+ return *qt_drag_default_pixmap();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformdrag_qpa.h b/src/gui/kernel/qplatformdrag_qpa.h
index 0c215071d3..7d22c69947 100644
--- a/src/gui/kernel/qplatformdrag_qpa.h
+++ b/src/gui/kernel/qplatformdrag_qpa.h
@@ -43,6 +43,7 @@
#define QPLATFORMDRAG_H
#include <QtCore/qglobal.h>
+#include <QtGui/QPixmap>
QT_BEGIN_HEADER
@@ -51,18 +52,54 @@ QT_BEGIN_NAMESPACE
class QMimeData;
class QMouseEvent;
+class QDrag;
+class QObject;
+class QEvent;
+class QPlatformDragPrivate;
-class QPlatformDrag
+class Q_GUI_EXPORT QPlatformDropQtResponse
{
public:
- virtual ~QPlatformDrag() {}
+ QPlatformDropQtResponse(bool accepted, Qt::DropAction acceptedAction);
+ bool isAccepted() const;
+ Qt::DropAction acceptedAction() const;
+private:
+ bool m_accepted;
+ Qt::DropAction m_accepted_action;
+
+};
+
+class Q_GUI_EXPORT QPlatformDragQtResponse : public QPlatformDropQtResponse
+{
+public:
+ QPlatformDragQtResponse(bool accepted, Qt::DropAction acceptedAction, QRect answerRect);
+
+ QRect answerRect() const;
+
+private:
+ QRect m_answer_rect;
+};
+
+class Q_GUI_EXPORT QPlatformDrag
+{
+ Q_DECLARE_PRIVATE(QPlatformDrag)
+public:
+ QPlatformDrag();
+ virtual ~QPlatformDrag();
+
+ QDrag *currentDrag() const;
virtual QMimeData *platformDropData() = 0;
- virtual void startDrag() {}
- virtual void move(const QMouseEvent *me) = 0;
- virtual void drop(const QMouseEvent *me) = 0;
- virtual void cancel() = 0;
+ virtual Qt::DropAction drag(QDrag *m_drag) = 0;
+ void updateAction(Qt::DropAction action);
+
+ Qt::DropAction defaultAction(Qt::DropActions possibleActions, Qt::KeyboardModifiers modifiers) const;
+
+ static QPixmap defaultPixmap();
+
+private:
+ QPlatformDragPrivate *d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
index 7237849011..f87a2956a3 100644
--- a/src/gui/kernel/qplatformnativeinterface_qpa.cpp
+++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
@@ -132,7 +132,7 @@ void QPlatformNativeInterface::setWindowProperty(QPlatformWindow *window, const
The event filter function set here is called for all messages
received from the platform if they are given type \eventType.
- It is \i not called for messages that are not meant for Qt objects.
+ It is \e not called for messages that are not meant for Qt objects.
The type of event is specific to the platform plugin chosen at run-time.
diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h
index e4b9b762b1..7d74698074 100644
--- a/src/gui/kernel/qplatformscreen_qpa.h
+++ b/src/gui/kernel/qplatformscreen_qpa.h
@@ -63,21 +63,12 @@ class QPlatformBackingStore;
class QPlatformOpenGLContext;
class QPlatformScreenPrivate;
class QPlatformWindow;
+class QPlatformScreenPageFlipper;
class QScreen;
class QSurfaceFormat;
typedef QPair<qreal, qreal> QDpi;
-class Q_GUI_EXPORT QPlatformScreenPageFlipper : public QObject
-{
- Q_OBJECT
-public:
- virtual bool displayBuffer(void *bufferHandle) = 0;
-
- signals:
- void bufferDisplayed(void *bufferHandle);
- void bufferReleased(void *bufferHandle);
-};
class Q_GUI_EXPORT QPlatformScreen
{
diff --git a/config.tests/unix/doubleformat/doubleformattest.cpp b/src/gui/kernel/qplatformscreenpageflipper_qpa.cpp
index 1a182c668a..d652e34e5e 100644
--- a/config.tests/unix/doubleformat/doubleformattest.cpp
+++ b/src/gui/kernel/qplatformscreenpageflipper_qpa.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,28 +39,45 @@
**
****************************************************************************/
-/*
+#include "qplatformscreenpageflipper_qpa.h"
-LE: strings | grep 0123ABCD0123ABCD
-BE: strings | grep DCBA3210DCBA3210
+QT_BEGIN_NAMESPACE
-LE arm-swapped-dword-order: strings | grep ABCD0123ABCD0123
-BE arm-swapped-dword-order: strings | grep 3210DCBA3210DCBA (untested)
+QPlatformScreenBuffer::QPlatformScreenBuffer()
+ : m_destroyed(false)
+ , m_ready(true)
+{
+
+}
+
+QPlatformScreenBuffer::~QPlatformScreenBuffer()
+{
-tested on x86, arm-le (gp), aix
+}
+
+bool QPlatformScreenBuffer::isDestroyed() const
+{
+ return m_destroyed;
+}
-*/
+bool QPlatformScreenBuffer::isReady() const
+{
+ return m_ready;
+}
-#include <stdlib.h>
+void QPlatformScreenBuffer::aboutToBeDisplayed()
+{
+}
-// equals static char c [] = "0123ABCD0123ABCD\0\0\0\0\0\0\0"
-static double d [] = { 710524581542275055616.0, 710524581542275055616.0, 0.0 };
+void QPlatformScreenBuffer::displayed()
+{
+}
-int main(int argc, char **argv)
+QPlatformScreenPageFlipper::QPlatformScreenPageFlipper(QObject *parent)
+ :QObject(parent)
{
- // make sure the linker doesn't throw away the arrays
- double *d2 = (double *) d;
- if (argc > 3)
- d[1] += 1;
- return d2[0] + d[2] + atof(argv[1]);
+
}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/image/qvolatileimagedata_p.h b/src/gui/kernel/qplatformscreenpageflipper_qpa.h
index 59e1be12e3..850f9d8d2f 100644
--- a/src/gui/image/qvolatileimagedata_p.h
+++ b/src/gui/kernel/qplatformscreenpageflipper_qpa.h
@@ -39,46 +39,49 @@
**
****************************************************************************/
-#ifndef QVOLATILEIMAGEDATA_P_H
-#define QVOLATILEIMAGEDATA_P_H
+#ifndef QPLATFORMSCREENPAGEFLIPPER_QPA_H
+#define QPLATFORMSCREENPAGEFLIPPER_QPA_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qimage.h>
-#include <QtCore/qshareddata.h>
+#include <QtCore/QObject>
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QVolatileImageData : public QSharedData
+class Q_GUI_EXPORT QPlatformScreenBuffer {
+public:
+ QPlatformScreenBuffer();
+ virtual ~QPlatformScreenBuffer();
+
+ bool isDestroyed() const;
+ bool isReady() const;
+
+ virtual void aboutToBeDisplayed();
+ virtual void displayed();
+ virtual void release() = 0;
+
+ virtual void *handle() const = 0;
+
+protected:
+ bool m_destroyed;
+ bool m_ready;
+};
+
+class Q_GUI_EXPORT QPlatformScreenPageFlipper : public QObject
{
+ Q_OBJECT
public:
- QVolatileImageData();
- QVolatileImageData(int w, int h, QImage::Format format);
- QVolatileImageData(const QImage &sourceImage);
- QVolatileImageData(void *nativeImage, void *nativeMask);
- QVolatileImageData(const QVolatileImageData &other);
- ~QVolatileImageData();
+ explicit QPlatformScreenPageFlipper(QObject *parent = 0);
- void beginDataAccess() const;
- void endDataAccess(bool readOnly = false) const;
- bool ensureFormat(QImage::Format format);
- void *duplicateNativeImage() const;
- void ensureImage();
+ virtual bool displayBuffer(QPlatformScreenBuffer *) = 0;
- QImage image;
- QPaintEngine *pengine;
+signals:
+ void bufferDisplayed(QPlatformScreenBuffer *);
+ void bufferReleased(QPlatformScreenBuffer *);
};
QT_END_NAMESPACE
-#endif // QVOLATILEIMAGEDATA_P_H
+QT_END_HEADER
+
+#endif // QPLATFORMSCREENPAGEFLIPPER_QPA_H
diff --git a/src/gui/kernel/qplatformtheme_qpa.cpp b/src/gui/kernel/qplatformtheme_qpa.cpp
index 3f6b69b902..3fdece70ea 100644
--- a/src/gui/kernel/qplatformtheme_qpa.cpp
+++ b/src/gui/kernel/qplatformtheme_qpa.cpp
@@ -102,6 +102,11 @@ QT_BEGIN_NAMESPACE
\sa themeHint(), QStyle::pixelMetric()
*/
+QPlatformTheme::~QPlatformTheme()
+{
+
+}
+
QPlatformMenu *QPlatformTheme::createPlatformMenu(QMenu *menu) const
{
Q_UNUSED(menu);
diff --git a/src/gui/kernel/qplatformtheme_qpa.h b/src/gui/kernel/qplatformtheme_qpa.h
index 31a52a9391..3610a3c1c8 100644
--- a/src/gui/kernel/qplatformtheme_qpa.h
+++ b/src/gui/kernel/qplatformtheme_qpa.h
@@ -99,6 +99,8 @@ public:
CdeKeyboardScheme
};
+ virtual ~QPlatformTheme();
+
virtual QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const;
virtual QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const;
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index 40a4ec07a6..5b77d97950 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -43,6 +43,7 @@
#include "private/qguiapplication_p.h"
#include "private/qtouchdevice_p.h"
#include <QAbstractEventDispatcher>
+#include <QPlatformDrag>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -447,14 +448,14 @@ int QWindowSystemInterface::windowSystemEventsQueued()
return QWindowSystemInterfacePrivate::windowSystemEventsQueued();
}
-Qt::DropAction QWindowSystemInterface::handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrag(w, dropData, p);
+ return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions);
}
-Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrop(w, dropData, p);
+ return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions);
}
/*!
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 836fb40bd7..6dae11ea81 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
class QMimeData;
class QTouchDevice;
+class QPlatformDragQtResponse;
+class QPlatformDropQtResponse;
class Q_GUI_EXPORT QWindowSystemInterface
@@ -122,8 +124,8 @@ public:
static void handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region);
// Drag and drop. These events are sent immediately.
- static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
- static Qt::DropAction handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
+ static QPlatformDragQtResponse handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
+ static QPlatformDropQtResponse handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp
index 113b767e9f..08ed0ae40f 100644
--- a/src/gui/math3d/qgenericmatrix.cpp
+++ b/src/gui/math3d/qgenericmatrix.cpp
@@ -53,9 +53,9 @@ QT_BEGIN_NAMESPACE
The QGenericMatrix template has three parameters:
\table
- \row \i N \i Number of columns.
- \row \i M \i Number of rows.
- \row \i T \i Element type that is visible to users of the class.
+ \row \li N \li Number of columns.
+ \row \li M \li Number of rows.
+ \row \li T \li Element type that is visible to users of the class.
\endtable
\sa QMatrix4x4
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 068b2e36f7..0eb3506779 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -62,11 +62,11 @@ QT_BEGIN_NAMESPACE
Internally the data is stored as column-major format, so as to be optimal for
passing to OpenGL functions, which expect column-major data.
- When using these functions be aware that they return data in \bold{column-major}
+ When using these functions be aware that they return data in \b{column-major}
format:
\list
- \o data()
- \o constData()
+ \li data()
+ \li constData()
\endlist
\sa QVector3D, QGenericMatrix
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 897fa356d3..3c3581f3f4 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
The QVector2D class can also be used to represent vertices in 2D space.
We therefore do not need to provide a separate vertex class.
- \bold{Note:} By design values in the QVector2D instance are stored as \c float.
+ \b{Note:} By design values in the QVector2D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector2D
functions are represented by \c double values, it is possible to
lose precision.
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 5251f9c015..adf3da4010 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
The QVector3D class can also be used to represent vertices in 3D space.
We therefore do not need to provide a separate vertex class.
- \bold{Note:} By design values in the QVector3D instance are stored as \c float.
+ \b{Note:} By design values in the QVector3D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector3D
functions are represented by \c double values, it is possible to
lose precision.
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index e7ee46b88b..6b29221d92 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
The QVector4D class can also be used to represent vertices in 4D space.
We therefore do not need to provide a separate vertex class.
- \bold{Note:} By design values in the QVector4D instance are stored as \c float.
+ \b{Note:} By design values in the QVector4D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector4D
functions are represented by \c double values, it is possible to
lose precision.
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index a523cd2cf1..cc5750490d 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -83,10 +83,10 @@ QT_BEGIN_NAMESPACE
A framebuffer object has several characteristics:
\list
- \i \link setSamples() Number of samples per pixels.\endlink
- \i \link setAttachment() Depth and/or stencil attachments.\endlink
- \i \link setTextureTarget() Texture target.\endlink
- \i \link setInternalTextureFormat() Internal texture format.\endlink
+ \li \link setSamples() Number of samples per pixels.\endlink
+ \li \link setAttachment() Depth and/or stencil attachments.\endlink
+ \li \link setTextureTarget() Texture target.\endlink
+ \li \link setInternalTextureFormat() Internal texture format.\endlink
\endlist
Note that the desired attachments or number of samples per pixels might not
@@ -407,6 +407,12 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
if (samples == 0) {
glGenTextures(1, &texture);
glBindTexture(target, texture);
+
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if (mipmap) {
@@ -421,10 +427,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
}
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
target, texture, 0);
@@ -655,7 +657,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
generates a 2D OpenGL texture (using the \c{GL_TEXTURE_2D} target),
which is used as the internal rendering target.
- \bold{It is important to have a current OpenGL context when creating a
+ \b{It is important to have a current OpenGL context when creating a
QOpenGLFramebufferObject, otherwise initialization will fail.}
When using a QPainter to paint to a QOpenGLFramebufferObject you should take
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 6850eac59e..fe9b370189 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -309,15 +309,15 @@ struct QBrushDataPointerDeleter
otherwise false. A brush is considered opaque if:
\list
- \o The alpha component of the color() is 255.
- \o Its texture() does not have an alpha channel and is not a QBitmap.
- \o The colors in the gradient() all have an alpha component that is 255.
+ \li The alpha component of the color() is 255.
+ \li Its texture() does not have an alpha channel and is not a QBitmap.
+ \li The colors in the gradient() all have an alpha component that is 255.
\endlist
\table 100%
\row
- \o \inlineimage brush-outline.png Outlines
- \o
+ \li \inlineimage brush-outline.png Outlines
+ \li
To specify the style and color of lines and outlines, use the
QPainter's \l {QPen}{pen} combined with Qt::PenStyle and
@@ -826,10 +826,10 @@ Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
is considered opaque if:
\list
- \i The alpha component of the color() is 255.
- \i Its texture() does not have an alpha channel and is not a QBitmap.
- \i The colors in the gradient() all have an alpha component that is 255.
- \i It is an extended radial gradient.
+ \li The alpha component of the color() is 255.
+ \li Its texture() does not have an alpha channel and is not a QBitmap.
+ \li The colors in the gradient() all have an alpha component that is 255.
+ \li It is an extended radial gradient.
\endlist
*/
@@ -1178,12 +1178,12 @@ QDataStream &operator>>(QDataStream &s, QBrush &b)
Qt currently supports three types of gradient fills:
\list
- \o \e Linear gradients interpolate colors between start and end points.
- \o \e Simple radial gradients interpolate colors between a focal point
+ \li \e Linear gradients interpolate colors between start and end points.
+ \li \e Simple radial gradients interpolate colors between a focal point
and end points on a circle surrounding it.
- \o \e Extended radial gradients interpolate colors between a center and
+ \li \e Extended radial gradients interpolate colors between a center and
a focal circle.
- \o \e Conical gradients interpolate colors around a center point.
+ \li \e Conical gradients interpolate colors around a center point.
\endlist
A gradient's type can be retrieved using the type() function.
@@ -1191,13 +1191,13 @@ QDataStream &operator>>(QDataStream &s, QBrush &b)
\table
\header
- \o QLinearGradient
- \o QRadialGradient
- \o QConicalGradient
+ \li QLinearGradient
+ \li QRadialGradient
+ \li QConicalGradient
\row
- \o \inlineimage qgradient-linear.png
- \o \inlineimage qgradient-radial.png
- \o \inlineimage qgradient-conical.png
+ \li \inlineimage qgradient-linear.png
+ \li \inlineimage qgradient-radial.png
+ \li \inlineimage qgradient-conical.png
\endtable
The colors in a gradient are defined using stop points of the
@@ -1232,13 +1232,13 @@ QDataStream &operator>>(QDataStream &s, QBrush &b)
\table
\row
- \o \inlineimage qradialgradient-pad.png
- \o \inlineimage qradialgradient-repeat.png
- \o \inlineimage qradialgradient-reflect.png
+ \li \inlineimage qradialgradient-pad.png
+ \li \inlineimage qradialgradient-repeat.png
+ \li \inlineimage qradialgradient-reflect.png
\row
- \o \l {QGradient::PadSpread}{PadSpread}
- \o \l {QGradient::RepeatSpread}{RepeatSpread}
- \o \l {QGradient::ReflectSpread}{ReflectSpread}
+ \li \l {QGradient::PadSpread}{PadSpread}
+ \li \l {QGradient::RepeatSpread}{RepeatSpread}
+ \li \l {QGradient::ReflectSpread}{ReflectSpread}
\endtable
Note that the setSpread() function only has effect for linear and
@@ -1537,13 +1537,13 @@ bool QGradient::operator==(const QGradient &gradient) const
\table
\row
- \o \inlineimage qlineargradient-pad.png
- \o \inlineimage qlineargradient-reflect.png
- \o \inlineimage qlineargradient-repeat.png
+ \li \inlineimage qlineargradient-pad.png
+ \li \inlineimage qlineargradient-reflect.png
+ \li \inlineimage qlineargradient-repeat.png
\row
- \o \l {QGradient::PadSpread}{PadSpread} (default)
- \o \l {QGradient::ReflectSpread}{ReflectSpread}
- \o \l {QGradient::RepeatSpread}{RepeatSpread}
+ \li \l {QGradient::PadSpread}{PadSpread} (default)
+ \li \l {QGradient::ReflectSpread}{ReflectSpread}
+ \li \l {QGradient::RepeatSpread}{RepeatSpread}
\endtable
The colors in a gradient is defined using stop points of the
@@ -1723,13 +1723,13 @@ void QLinearGradient::setFinalStop(const QPointF &stop)
\table
\row
- \o \inlineimage qradialgradient-pad.png
- \o \inlineimage qradialgradient-reflect.png
- \o \inlineimage qradialgradient-repeat.png
+ \li \inlineimage qradialgradient-pad.png
+ \li \inlineimage qradialgradient-reflect.png
+ \li \inlineimage qradialgradient-repeat.png
\row
- \o \l {QGradient::PadSpread}{PadSpread} (default)
- \o \l {QGradient::ReflectSpread}{ReflectSpread}
- \o \l {QGradient::RepeatSpread}{RepeatSpread}
+ \li \l {QGradient::PadSpread}{PadSpread} (default)
+ \li \l {QGradient::ReflectSpread}{ReflectSpread}
+ \li \l {QGradient::RepeatSpread}{RepeatSpread}
\endtable
The colors in a gradient is defined using stop points of the
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 96491918cd..f531565fb9 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -69,11 +69,11 @@ QT_BEGIN_NAMESPACE
\table
\header
- \o RGB \o HSV \o CMYK
+ \li RGB \li HSV \li CMYK
\row
- \o \inlineimage qcolor-rgb.png
- \o \inlineimage qcolor-hsv.png
- \o \inlineimage qcolor-cmyk.png
+ \li \inlineimage qcolor-rgb.png
+ \li \inlineimage qcolor-hsv.png
+ \li \inlineimage qcolor-cmyk.png
\endtable
The QColor constructor creates the color based on RGB values. To
@@ -194,20 +194,20 @@ QT_BEGIN_NAMESPACE
HSV, like RGB, has three components:
\list
- \o H, for hue, is in the range 0 to 359 if the color is chromatic (not
+ \li H, for hue, is in the range 0 to 359 if the color is chromatic (not
gray), or meaningless if it is gray. It represents degrees on the
color wheel familiar to most people. Red is 0 (degrees), green is
120, and blue is 240.
\inlineimage qcolor-hue.png
- \o S, for saturation, is in the range 0 to 255, and the bigger it is,
+ \li S, for saturation, is in the range 0 to 255, and the bigger it is,
the stronger the color is. Grayish colors have saturation near 0; very
strong colors have saturation near 255.
\inlineimage qcolor-saturation.png
- \o V, for value, is in the range 0 to 255 and represents lightness or
+ \li V, for value, is in the range 0 to 255 and represents lightness or
brightness of the color. 0 is black; 255 is as far from black as
possible.
@@ -498,16 +498,16 @@ QString QColor::name() const
of these formats:
\list
- \i #RGB (each of R, G, and B is a single hex digit)
- \i #RRGGBB
- \i #RRRGGGBBB
- \i #RRRRGGGGBBBB
- \i A name from the list of colors defined in the list of \l{SVG color keyword names}
+ \li #RGB (each of R, G, and B is a single hex digit)
+ \li #RRGGBB
+ \li #RRRGGGBBB
+ \li #RRRRGGGGBBBB
+ \li A name from the list of colors defined in the list of \l{SVG color keyword names}
provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
These color names work on all platforms. Note that these color names are \e not the
same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
refer to the same color.
- \i \c transparent - representing the absence of a color.
+ \li \c transparent - representing the absence of a color.
\endlist
The color is invalid if \a name cannot be parsed.
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 6b5eb14f5f..ced2e4548c 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -111,8 +111,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qmatrix-simpletransformation.png
- \o
+ \li \inlineimage qmatrix-simpletransformation.png
+ \li
\snippet doc/src/snippets/matrix/matrix.cpp 0
\endtable
@@ -123,8 +123,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qmatrix-combinedtransformation.png
- \o
+ \li \inlineimage qmatrix-combinedtransformation.png
+ \li
\snippet doc/src/snippets/matrix/matrix.cpp 1
\endtable
@@ -171,8 +171,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qmatrix-combinedtransformation.png
- \o
+ \li \inlineimage qmatrix-combinedtransformation.png
+ \li
\snippet doc/src/snippets/matrix/matrix.cpp 2
\endtable
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index 594259367c..15495cace8 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QPaintDevice;
-class QPaintEnginePrivate
+class Q_GUI_EXPORT QPaintEnginePrivate
{
Q_DECLARE_PUBLIC(QPaintEngine)
public:
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 43429abe8a..0f5468df4e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -984,41 +984,41 @@ void QPainterPrivate::updateState(QPainterState *newState)
\list
- \o font() is the font used for drawing text. If the painter
+ \li font() is the font used for drawing text. If the painter
isActive(), you can retrieve information about the currently set
font, and its metrics, using the fontInfo() and fontMetrics()
functions respectively.
- \o brush() defines the color or pattern that is used for filling
+ \li brush() defines the color or pattern that is used for filling
shapes.
- \o pen() defines the color or stipple that is used for drawing
+ \li pen() defines the color or stipple that is used for drawing
lines or boundaries.
- \o backgroundMode() defines whether there is a background() or
+ \li backgroundMode() defines whether there is a background() or
not, i.e it is either Qt::OpaqueMode or Qt::TransparentMode.
- \o background() only applies when backgroundMode() is \l
+ \li background() only applies when backgroundMode() is \l
Qt::OpaqueMode and pen() is a stipple. In that case, it
describes the color of the background pixels in the stipple.
- \o brushOrigin() defines the origin of the tiled brushes, normally
+ \li brushOrigin() defines the origin of the tiled brushes, normally
the origin of widget's background.
- \o viewport(), window(), worldTransform() make up the painter's coordinate
+ \li viewport(), window(), worldTransform() make up the painter's coordinate
transformation system. For more information, see the \l
{Coordinate Transformations} section and the \l {Coordinate
System} documentation.
- \o hasClipping() tells whether the painter clips at all. (The paint
+ \li hasClipping() tells whether the painter clips at all. (The paint
device clips, too.) If the painter clips, it clips to clipRegion().
- \o layoutDirection() defines the layout direction used by the
+ \li layoutDirection() defines the layout direction used by the
painter when drawing text.
- \o worldMatrixEnabled() tells whether world transformation is enabled.
+ \li worldMatrixEnabled() tells whether world transformation is enabled.
- \o viewTransformEnabled() tells whether view transformation is
+ \li viewTransformEnabled() tells whether view transformation is
enabled.
\endlist
@@ -1052,9 +1052,9 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table 100%
\row
- \o \inlineimage qpainter-basicdrawing.png
- \o
- \bold {Basic Drawing Example}
+ \li \inlineimage qpainter-basicdrawing.png
+ \li
+ \b {Basic Drawing Example}
The \l {painting/basicdrawing}{Basic Drawing} example shows how to
display basic graphics primitives in a variety of styles using the
@@ -1068,8 +1068,8 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table 100%
\row
- \o
- \bold {Painter Paths example}
+ \li
+ \b {Painter Paths example}
The QPainterPath class provides a container for painting
operations, enabling graphical shapes to be constructed and
@@ -1078,7 +1078,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
The \l {painting/painterpaths}{Painter Paths} example shows how
painter paths can be used to build complex shapes for rendering.
- \o \inlineimage qpainter-painterpaths.png
+ \li \inlineimage qpainter-painterpaths.png
\endtable
QPainter also provides the fillPath() function which fills the
@@ -1096,13 +1096,13 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table
\header
- \o \l {painting/deform}{Vector Deformation}
- \o \l {painting/gradients}{Gradients}
- \o \l {painting/pathstroke}{Path Stroking}
+ \li \l {painting/deform}{Vector Deformation}
+ \li \l {painting/gradients}{Gradients}
+ \li \l {painting/pathstroke}{Path Stroking}
\row
- \o \inlineimage qpainter-vectordeformation.png
- \o \inlineimage qpainter-gradients.png
- \o \inlineimage qpainter-pathstroking.png
+ \li \inlineimage qpainter-vectordeformation.png
+ \li \inlineimage qpainter-gradients.png
+ \li \inlineimage qpainter-pathstroking.png
\endtable
@@ -1136,9 +1136,9 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table 100%
\row
- \o \inlineimage qpainter-concentriccircles.png
- \o
- \bold {Concentric Circles Example}
+ \li \inlineimage qpainter-concentriccircles.png
+ \li
+ \b {Concentric Circles Example}
The \l {painting/concentriccircles}{Concentric Circles} example
shows the improved rendering quality that can be obtained using
@@ -1176,12 +1176,12 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table
\header
- \o nop \o rotate() \o scale() \o translate()
+ \li nop \li rotate() \li scale() \li translate()
\row
- \o \inlineimage qpainter-clock.png
- \o \inlineimage qpainter-rotation.png
- \o \inlineimage qpainter-scale.png
- \o \inlineimage qpainter-translation.png
+ \li \inlineimage qpainter-clock.png
+ \li \inlineimage qpainter-rotation.png
+ \li \inlineimage qpainter-scale.png
+ \li \inlineimage qpainter-translation.png
\endtable
The most commonly used transformations are scaling, rotation,
@@ -1200,15 +1200,15 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table 100%
\row
- \o
- \bold {Affine Transformations Example}
+ \li
+ \b {Affine Transformations Example}
The \l {painting/affine}{Affine Transformations} example shows Qt's
ability to perform affine transformations on painting
operations. The demo also allows the user to experiment with the
transformation operations and see the results immediately.
- \o \inlineimage qpainter-affinetransformations.png
+ \li \inlineimage qpainter-affinetransformations.png
\endtable
All the tranformation operations operate on the transformation
@@ -1282,10 +1282,10 @@ void QPainterPrivate::updateState(QPainterState *newState)
\table 100%
\row
- \o \inlineimage qpainter-compositiondemo.png
+ \li \inlineimage qpainter-compositiondemo.png
- \o
- \bold {Composition Modes Example}
+ \li
+ \b {Composition Modes Example}
The \l {painting/composition}{Composition Modes} example, available in
Qt's examples directory, allows you to experiment with the various
@@ -1333,14 +1333,14 @@ void QPainterPrivate::updateState(QPainterState *newState)
\list
- \o Raster - This backend implements all rendering in pure software
+ \li Raster - This backend implements all rendering in pure software
and is always used to render into QImages. For optimal performance
only use the format types QImage::Format_ARGB32_Premultiplied,
QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
including QImage::Format_ARGB32, has significantly worse
performance. This engine is used by default for QWidget and QPixmap.
- \o OpenGL 2.0 (ES) - This backend is the primary backend for
+ \li OpenGL 2.0 (ES) - This backend is the primary backend for
hardware accelerated graphics. It can be run on desktop machines
and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
specification. This includes most graphics chips produced in the
@@ -1348,7 +1348,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
onto a QOpenGLWidget or by passing \c {-graphicssystem opengl} on the
command line when the underlying system supports it.
- \o OpenVG - This backend implements the Khronos standard for 2D
+ \li OpenVG - This backend implements the Khronos standard for 2D
and Vector Graphics. It is primarily for embedded devices with
hardware support for OpenVG. The engine can be enabled by
passing \c {-graphicssystem openvg} on the command line when
@@ -1360,26 +1360,26 @@ void QPainterPrivate::updateState(QPainterState *newState)
\list
- \o Simple transformations, meaning translation and scaling, pluss
+ \li Simple transformations, meaning translation and scaling, pluss
0, 90, 180, 270 degree rotations.
- \o \c drawPixmap() in combination with simple transformations and
+ \li \c drawPixmap() in combination with simple transformations and
opacity with non-smooth transformation mode
(\c QPainter::SmoothPixmapTransform not enabled as a render hint).
- \o Rectangle fills with solid color, two-color linear gradients
+ \li Rectangle fills with solid color, two-color linear gradients
and simple transforms.
- \o Rectangular clipping with simple transformations and intersect
+ \li Rectangular clipping with simple transformations and intersect
clip.
- \o Composition Modes \c QPainter::CompositionMode_Source and
+ \li Composition Modes \c QPainter::CompositionMode_Source and
QPainter::CompositionMode_SourceOver
- \o Rounded rectangle filling using solid color and two-color
+ \li Rounded rectangle filling using solid color and two-color
linear gradients fills.
- \o 3x3 patched pixmaps, via qDrawBorderPixmap.
+ \li 3x3 patched pixmaps, via qDrawBorderPixmap.
\endlist
@@ -1963,14 +1963,14 @@ QPaintEngine *QPainter::paintEngine() const
2 engine:
\list
- \i blending is disabled
- \i the depth, stencil and scissor tests are disabled
- \i the active texture unit is reset to 0
- \i the depth mask, depth function and the clear depth are reset to their
+ \li blending is disabled
+ \li the depth, stencil and scissor tests are disabled
+ \li the active texture unit is reset to 0
+ \li the depth mask, depth function and the clear depth are reset to their
default values
- \i the stencil mask, stencil operation and stencil function are reset to
+ \li the stencil mask, stencil operation and stencil function are reset to
their default values
- \i the current color is reset to solid white
+ \li the current color is reset to solid white
\endlist
If, for example, the OpenGL polygon mode is changed by the user inside a
@@ -2885,10 +2885,10 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
The following functions can transform the coordinate system without using
a QMatrix:
\list
- \i translate()
- \i scale()
- \i shear()
- \i rotate()
+ \li translate()
+ \li scale()
+ \li shear()
+ \li rotate()
\endlist
They operate on the painter's worldMatrix() and are implemented like this:
@@ -3360,8 +3360,8 @@ void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
\table 100%
\row
- \o \inlineimage qpainter-path.png
- \o
+ \li \inlineimage qpainter-path.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
\endtable
@@ -3405,8 +3405,8 @@ void QPainter::drawPath(const QPainterPath &path)
\table 100%
\row
- \o \inlineimage qpainter-line.png
- \o
+ \li \inlineimage qpainter-line.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
\endtable
@@ -3452,8 +3452,8 @@ void QPainter::drawPath(const QPainterPath &path)
\table 100%
\row
- \o \inlineimage qpainter-rectangle.png
- \o
+ \li \inlineimage qpainter-rectangle.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
\endtable
@@ -4121,8 +4121,8 @@ const QFont &QPainter::font() const
\table 100%
\row
- \o \inlineimage qpainter-roundrect.png
- \o
+ \li \inlineimage qpainter-roundrect.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
\endtable
@@ -4221,8 +4221,8 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
\table 100%
\row
- \o \inlineimage qpainter-ellipse.png
- \o
+ \li \inlineimage qpainter-ellipse.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
\endtable
@@ -4347,8 +4347,8 @@ void QPainter::drawEllipse(const QRect &r)
\table 100%
\row
- \o \inlineimage qpainter-arc.png
- \o
+ \li \inlineimage qpainter-arc.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
\endtable
@@ -4411,8 +4411,8 @@ void QPainter::drawArc(const QRectF &r, int a, int alen)
\table 100%
\row
- \o \inlineimage qpainter-pie.png
- \o
+ \li \inlineimage qpainter-pie.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
\endtable
@@ -4480,8 +4480,8 @@ void QPainter::drawPie(const QRectF &r, int a, int alen)
\table 100%
\row
- \o \inlineimage qpainter-chord.png
- \o
+ \li \inlineimage qpainter-chord.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
\endtable
@@ -4696,7 +4696,7 @@ void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
\endtable
@@ -4802,8 +4802,8 @@ void QPainter::drawPolyline(const QPoint *points, int pointCount)
\table 100%
\row
- \o \inlineimage qpainter-polygon.png
- \o
+ \li \inlineimage qpainter-polygon.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
\endtable
@@ -4915,8 +4915,8 @@ void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fi
\table 100%
\row
- \o \inlineimage qpainter-polygon.png
- \o
+ \li \inlineimage qpainter-polygon.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
\endtable
@@ -5039,7 +5039,7 @@ static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransfor
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
\endtable
@@ -5952,8 +5952,8 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br
\table 100%
\row
- \o \inlineimage qpainter-text.png
- \o
+ \li \inlineimage qpainter-text.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
\endtable
@@ -5962,20 +5962,20 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br
OR of the following flags:
\list
- \o Qt::AlignLeft
- \o Qt::AlignRight
- \o Qt::AlignHCenter
- \o Qt::AlignJustify
- \o Qt::AlignTop
- \o Qt::AlignBottom
- \o Qt::AlignVCenter
- \o Qt::AlignCenter
- \o Qt::TextDontClip
- \o Qt::TextSingleLine
- \o Qt::TextExpandTabs
- \o Qt::TextShowMnemonic
- \o Qt::TextWordWrap
- \o Qt::TextIncludeTrailingSpaces
+ \li Qt::AlignLeft
+ \li Qt::AlignRight
+ \li Qt::AlignHCenter
+ \li Qt::AlignJustify
+ \li Qt::AlignTop
+ \li Qt::AlignBottom
+ \li Qt::AlignVCenter
+ \li Qt::AlignCenter
+ \li Qt::TextDontClip
+ \li Qt::TextSingleLine
+ \li Qt::TextExpandTabs
+ \li Qt::TextShowMnemonic
+ \li Qt::TextWordWrap
+ \li Qt::TextIncludeTrailingSpaces
\endlist
\sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()
@@ -6044,18 +6044,18 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *
the following flags:
\list
- \o Qt::AlignLeft
- \o Qt::AlignRight
- \o Qt::AlignHCenter
- \o Qt::AlignJustify
- \o Qt::AlignTop
- \o Qt::AlignBottom
- \o Qt::AlignVCenter
- \o Qt::AlignCenter
- \o Qt::TextSingleLine
- \o Qt::TextExpandTabs
- \o Qt::TextShowMnemonic
- \o Qt::TextWordWrap
+ \li Qt::AlignLeft
+ \li Qt::AlignRight
+ \li Qt::AlignHCenter
+ \li Qt::AlignJustify
+ \li Qt::AlignTop
+ \li Qt::AlignBottom
+ \li Qt::AlignVCenter
+ \li Qt::AlignCenter
+ \li Qt::TextSingleLine
+ \li Qt::TextExpandTabs
+ \li Qt::TextShowMnemonic
+ \li Qt::TextWordWrap
\endlist
By default, QPainter draws text anti-aliased.
@@ -6472,18 +6472,18 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
The \a flags argument is a bitwise OR of the following flags:
\list
- \o Qt::AlignLeft
- \o Qt::AlignRight
- \o Qt::AlignHCenter
- \o Qt::AlignTop
- \o Qt::AlignBottom
- \o Qt::AlignVCenter
- \o Qt::AlignCenter
- \o Qt::TextSingleLine
- \o Qt::TextExpandTabs
- \o Qt::TextShowMnemonic
- \o Qt::TextWordWrap
- \o Qt::TextIncludeTrailingSpaces
+ \li Qt::AlignLeft
+ \li Qt::AlignRight
+ \li Qt::AlignHCenter
+ \li Qt::AlignTop
+ \li Qt::AlignBottom
+ \li Qt::AlignVCenter
+ \li Qt::AlignCenter
+ \li Qt::TextSingleLine
+ \li Qt::TextExpandTabs
+ \li Qt::TextShowMnemonic
+ \li Qt::TextWordWrap
+ \li Qt::TextIncludeTrailingSpaces
\endlist
If several of the horizontal or several of the vertical alignment
flags are set, the resulting alignment is undefined.
@@ -6691,7 +6691,7 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
\endtable
@@ -7675,7 +7675,7 @@ void QPainterState::init(QPainter *p) {
\table 100%
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
\endtable
@@ -7791,21 +7791,21 @@ void QPainterState::init(QPainter *p) {
\target GetFunction
\table
- \header \o Property Flag \o Current Property Value
- \row \o QPaintEngine::DirtyBackground \o backgroundBrush()
- \row \o QPaintEngine::DirtyBackgroundMode \o backgroundMode()
- \row \o QPaintEngine::DirtyBrush \o brush()
- \row \o QPaintEngine::DirtyBrushOrigin \o brushOrigin()
- \row \o QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
- \o clipOperation()
- \row \o QPaintEngine::DirtyClipPath \o clipPath()
- \row \o QPaintEngine::DirtyClipRegion \o clipRegion()
- \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
- \row \o QPaintEngine::DirtyFont \o font()
- \row \o QPaintEngine::DirtyTransform \o transform()
- \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
- \row \o QPaintEngine::DirtyPen \o pen()
- \row \o QPaintEngine::DirtyHints \o renderHints()
+ \header \li Property Flag \li Current Property Value
+ \row \li QPaintEngine::DirtyBackground \li backgroundBrush()
+ \row \li QPaintEngine::DirtyBackgroundMode \li backgroundMode()
+ \row \li QPaintEngine::DirtyBrush \li brush()
+ \row \li QPaintEngine::DirtyBrushOrigin \li brushOrigin()
+ \row \li QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
+ \li clipOperation()
+ \row \li QPaintEngine::DirtyClipPath \li clipPath()
+ \row \li QPaintEngine::DirtyClipRegion \li clipRegion()
+ \row \li QPaintEngine::DirtyCompositionMode \li compositionMode()
+ \row \li QPaintEngine::DirtyFont \li font()
+ \row \li QPaintEngine::DirtyTransform \li transform()
+ \row \li QPaintEngine::DirtyClipEnabled \li isClipEnabled()
+ \row \li QPaintEngine::DirtyPen \li pen()
+ \row \li QPaintEngine::DirtyHints \li renderHints()
\endtable
The QPaintEngineState class also provide the painter() function
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 25dd134401..eb67709318 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -227,8 +227,8 @@ static void qt_debug_path(const QPainterPath &path)
\table 100%
\row
- \o \inlineimage qpainterpath-construction.png
- \o
+ \li \inlineimage qpainterpath-construction.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 0
\endtable
@@ -241,11 +241,11 @@ static void qt_debug_path(const QPainterPath &path)
\table
\header
- \o Qt::OddEvenFill
- \o Qt::WindingFill
+ \li Qt::OddEvenFill
+ \li Qt::WindingFill
\row
- \o \inlineimage qt-fillrule-oddeven.png
- \o \inlineimage qt-fillrule-winding.png
+ \li \inlineimage qt-fillrule-oddeven.png
+ \li \inlineimage qt-fillrule-winding.png
\endtable
See the Qt::FillRule documentation for the definition of the
@@ -316,11 +316,11 @@ static void qt_debug_path(const QPainterPath &path)
\table
\header
- \o \l {painting/painterpaths}{Painter Paths Example}
- \o \l {painting/deform}{Vector Deformation Example}
+ \li \l {painting/painterpaths}{Painter Paths Example}
+ \li \l {painting/deform}{Vector Deformation Example}
\row
- \o \inlineimage qpainterpath-example.png
- \o \inlineimage qpainterpath-demo.png
+ \li \inlineimage qpainterpath-example.png
+ \li \inlineimage qpainterpath-demo.png
\endtable
\sa QPainterPathStroker, QPainter, QRegion, {Painter Paths Example}
@@ -731,8 +731,8 @@ void QPainterPath::lineTo(const QPointF &p)
\table 100%
\row
- \o \inlineimage qpainterpath-cubicto.png
- \o
+ \li \inlineimage qpainterpath-cubicto.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 1
\endtable
@@ -858,8 +858,8 @@ void QPainterPath::quadTo(const QPointF &c, const QPointF &e)
\table 100%
\row
- \o \inlineimage qpainterpath-arcto.png
- \o
+ \li \inlineimage qpainterpath-arcto.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 2
\endtable
@@ -970,8 +970,8 @@ QPointF QPainterPath::currentPosition() const
\table 100%
\row
- \o \inlineimage qpainterpath-addrectangle.png
- \o
+ \li \inlineimage qpainterpath-addrectangle.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 3
\endtable
@@ -1017,8 +1017,8 @@ void QPainterPath::addRect(const QRectF &r)
\table 100%
\row
- \o \inlineimage qpainterpath-addpolygon.png
- \o
+ \li \inlineimage qpainterpath-addpolygon.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 4
\endtable
@@ -1053,8 +1053,8 @@ void QPainterPath::addPolygon(const QPolygonF &polygon)
\table 100%
\row
- \o \inlineimage qpainterpath-addellipse.png
- \o
+ \li \inlineimage qpainterpath-addellipse.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 5
\endtable
@@ -1105,8 +1105,8 @@ void QPainterPath::addEllipse(const QRectF &boundingRect)
\table 100%
\row
- \o \inlineimage qpainterpath-addtext.png
- \o
+ \li \inlineimage qpainterpath-addtext.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpainterpath.cpp 6
\endtable
@@ -1281,11 +1281,11 @@ Qt::FillRule QPainterPath::fillRule() const
\table
\header
- \o Qt::OddEvenFill (default)
- \o Qt::WindingFill
+ \li Qt::OddEvenFill (default)
+ \li Qt::WindingFill
\row
- \o \inlineimage qt-fillrule-oddeven.png
- \o \inlineimage qt-fillrule-winding.png
+ \li \inlineimage qt-fillrule-oddeven.png
+ \li \inlineimage qt-fillrule-winding.png
\endtable
\sa fillRule()
@@ -2457,10 +2457,10 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,
functions:
\list
- \o setWidth()
- \o setCapStyle()
- \o setJoinStyle()
- \o setDashPattern()
+ \li setWidth()
+ \li setCapStyle()
+ \li setJoinStyle()
+ \li setDashPattern()
\endlist
The setDashPattern() function accepts both a Qt::PenStyle object
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 8d05eb56ff..77f0edc52f 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -104,21 +104,21 @@ typedef QPenPrivate QPenData;
\table
\row
- \o \inlineimage qpen-solid.png
- \o \inlineimage qpen-dash.png
- \o \inlineimage qpen-dot.png
+ \li \inlineimage qpen-solid.png
+ \li \inlineimage qpen-dash.png
+ \li \inlineimage qpen-dot.png
\row
- \o Qt::SolidLine
- \o Qt::DashLine
- \o Qt::DotLine
+ \li Qt::SolidLine
+ \li Qt::DashLine
+ \li Qt::DotLine
\row
- \o \inlineimage qpen-dashdot.png
- \o \inlineimage qpen-dashdotdot.png
- \o \inlineimage qpen-custom.png
+ \li \inlineimage qpen-dashdot.png
+ \li \inlineimage qpen-dashdotdot.png
+ \li \inlineimage qpen-custom.png
\row
- \o Qt::DashDotLine
- \o Qt::DashDotDotLine
- \o Qt::CustomDashLine
+ \li Qt::DashDotLine
+ \li Qt::DashDotDotLine
+ \li Qt::CustomDashLine
\endtable
Simply use the setStyle() function to convert the pen style to
@@ -153,13 +153,13 @@ typedef QPenPrivate QPenData;
\table
\row
- \o \inlineimage qpen-square.png
- \o \inlineimage qpen-flat.png
- \o \inlineimage qpen-roundcap.png
+ \li \inlineimage qpen-square.png
+ \li \inlineimage qpen-flat.png
+ \li \inlineimage qpen-roundcap.png
\row
- \o Qt::SquareCap
- \o Qt::FlatCap
- \o Qt::RoundCap
+ \li Qt::SquareCap
+ \li Qt::FlatCap
+ \li Qt::RoundCap
\endtable
The Qt::SquareCap style is a square line end that covers the end
@@ -183,13 +183,13 @@ typedef QPenPrivate QPenData;
\table
\row
- \o \inlineimage qpen-bevel.png
- \o \inlineimage qpen-miter.png
- \o \inlineimage qpen-roundjoin.png
+ \li \inlineimage qpen-bevel.png
+ \li \inlineimage qpen-miter.png
+ \li \inlineimage qpen-roundjoin.png
\row
- \o Qt::BevelJoin
- \o Qt::MiterJoin
- \o Qt::RoundJoin
+ \li Qt::BevelJoin
+ \li Qt::MiterJoin
+ \li Qt::RoundJoin
\endtable
The Qt::BevelJoin style fills the triangular notch between the two
@@ -213,8 +213,8 @@ typedef QPenPrivate QPenData;
\table 100%
\row
- \o \inlineimage qpen-demo.png
- \o \bold {\l {painting/pathstroke}{The Path Stroking Example}}
+ \li \inlineimage qpen-demo.png
+ \li \b {\l {painting/pathstroke}{The Path Stroking Example}}
The Path Stroking example shows Qt's built-in dash patterns and shows
how custom patterns can be used to extend the range of available
@@ -474,8 +474,8 @@ QVector<qreal> QPen::dashPattern() const
\table 100%
\row
- \o \inlineimage qpen-custom.png
- \o
+ \li \inlineimage qpen-custom.png
+ \li
\snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 3
\endtable
@@ -527,8 +527,8 @@ qreal QPen::dashOffset() const
to specify the dash pattern.
\table
- \row \o \inlineimage qpen-dashpattern.png
- \o For example, a pattern where each stroke is four units long, followed by a gap
+ \row \li \inlineimage qpen-dashpattern.png
+ \li For example, a pattern where each stroke is four units long, followed by a gap
of two units, will begin with the stroke when drawn as a line.
However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 48b0c00014..ebca1edddc 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -894,11 +894,11 @@ QRegion QRegion::intersect(const QRect &r) const
The rectangles \e must be optimally Y-X sorted and follow these restrictions:
\list
- \o The rectangles must not intersect.
- \o All rectangles with a given top coordinate must have the same height.
- \o No two rectangles may abut horizontally (they should be combined
+ \li The rectangles must not intersect.
+ \li All rectangles with a given top coordinate must have the same height.
+ \li No two rectangles may abut horizontally (they should be combined
into a single wider rectangle in that case).
- \o The rectangles must be sorted in ascending order, with Y as the major
+ \li The rectangles must be sorted in ascending order, with Y as the major
sort key and X as the minor sort key.
\endlist
\omit
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 363dd26bbf..e5c41efc15 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -156,8 +156,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qtransform-simpletransformation.png
- \o
+ \li \inlineimage qtransform-simpletransformation.png
+ \li
\snippet doc/src/snippets/transform/main.cpp 0
\endtable
@@ -168,8 +168,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qtransform-combinedtransformation.png
- \o
+ \li \inlineimage qtransform-combinedtransformation.png
+ \li
\snippet doc/src/snippets/transform/main.cpp 1
\endtable
@@ -218,8 +218,8 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage qtransform-combinedtransformation2.png
- \o
+ \li \inlineimage qtransform-combinedtransformation2.png
+ \li
\snippet doc/src/snippets/transform/main.cpp 2
\endtable
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 86de48b1dc..589c0f701f 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -100,14 +100,14 @@ QT_BEGIN_NAMESPACE
custom text object into a document:
\list
- \o Choose an \a objectType. The \a objectType is an integer with a
+ \li Choose an \a objectType. The \a objectType is an integer with a
value greater or equal to QTextFormat::UserObject.
- \o Create a QTextCharFormat object and set the object type to the
+ \li Create a QTextCharFormat object and set the object type to the
chosen type using the setObjectType() function.
- \o Implement the QTextObjectInterface class.
- \o Call QAbstractTextDocumentLayout::registerHandler() with an instance of your
+ \li Implement the QTextObjectInterface class.
+ \li Call QAbstractTextDocumentLayout::registerHandler() with an instance of your
QTextObjectInterface subclass to register your object type.
- \o Insert QChar::ObjectReplacementCharacter with the aforementioned
+ \li Insert QChar::ObjectReplacementCharacter with the aforementioned
QTextCharFormat of the chosen object type into the document.
As mentioned, the functions of QTextObjectInterface
\l{QTextObjectInterface::}{intrinsicSize()} and
@@ -269,17 +269,17 @@ QT_BEGIN_NAMESPACE
implementation of this function would have to do the following:
\list
- \o Determine the list of changed \l{QTextBlock}(s) using the parameters
+ \li Determine the list of changed \l{QTextBlock}(s) using the parameters
provided.
- \o Each QTextBlock object's corresponding QTextLayout object needs to
+ \li Each QTextBlock object's corresponding QTextLayout object needs to
be processed. You can access the \l{QTextBlock}'s layout using the
QTextBlock::layout() function. This processing should take the
document's page size into consideration.
- \o If the total number of pages changed, the pageCountChanged() signal
+ \li If the total number of pages changed, the pageCountChanged() signal
should be emitted.
- \o If the total size changed, the documentSizeChanged() signal should
+ \li If the total size changed, the documentSizeChanged() signal should
be emitted.
- \o The update() signal should be emitted to schedule a repaint of areas
+ \li The update() signal should be emitted to schedule a repaint of areas
in the layout that require repainting.
\endlist
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index ee833a06cf..c68452d55a 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -419,14 +419,14 @@ QFontEngineData::~QFontEngineData()
\target fontmatching
The font matching algorithm works as follows:
\list 1
- \o The specified font family is searched for.
- \o If not found, the styleHint() is used to select a replacement
+ \li The specified font family is searched for.
+ \li If not found, the styleHint() is used to select a replacement
family.
- \o Each replacement font family is searched for.
- \o If none of these are found or there was no styleHint(), "helvetica"
+ \li Each replacement font family is searched for.
+ \li If none of these are found or there was no styleHint(), "helvetica"
will be searched for.
- \o If "helvetica" isn't found Qt will try the lastResortFamily().
- \o If the lastResortFamily() isn't found Qt will try the
+ \li If "helvetica" isn't found Qt will try the lastResortFamily().
+ \li If the lastResortFamily() isn't found Qt will try the
lastResortFont() which will always return a name of some kind.
\endlist
@@ -440,10 +440,10 @@ QFontEngineData::~QFontEngineData()
Once a font is found, the remaining attributes are matched in order of
priority:
\list 1
- \o fixedPitch()
- \o pointSize() (see below)
- \o weight()
- \o style()
+ \li fixedPitch()
+ \li pointSize() (see below)
+ \li weight()
+ \li style()
\endlist
If you have a font which matches on family, even if none of the
@@ -861,35 +861,35 @@ int QFont::pointSize() const
\table
\header
- \o
- \o PreferDefaultHinting
- \o PreferNoHinting
- \o PreferVerticalHinting
- \o PreferFullHinting
+ \li
+ \li PreferDefaultHinting
+ \li PreferNoHinting
+ \li PreferVerticalHinting
+ \li PreferFullHinting
\row
- \o Windows Vista (w/o Platform Update) and earlier
- \o Full hinting
- \o Full hinting
- \o Full hinting
- \o Full hinting
+ \li Windows Vista (w/o Platform Update) and earlier
+ \li Full hinting
+ \li Full hinting
+ \li Full hinting
+ \li Full hinting
\row
- \o Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
- \o Full hinting
- \o Vertical hinting
- \o Vertical hinting
- \o Full hinting
+ \li Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
+ \li Full hinting
+ \li Vertical hinting
+ \li Vertical hinting
+ \li Full hinting
\row
- \o FreeType
- \o Operating System setting
- \o No hinting
- \o Vertical hinting (light)
- \o Full hinting
+ \li FreeType
+ \li Operating System setting
+ \li No hinting
+ \li Vertical hinting (light)
+ \li Full hinting
\row
- \o Cocoa on Mac OS X
- \o No hinting
- \o No hinting
- \o No hinting
- \o No hinting
+ \li Cocoa on Mac OS X
+ \li No hinting
+ \li No hinting
+ \li No hinting
+ \li No hinting
\endtable
\note Please be aware that altering the hinting preference on Windows is available through
@@ -2277,7 +2277,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
There are three ways to create a QFontInfo object.
\list 1
- \o Calling the QFontInfo constructor with a QFont creates a font
+ \li Calling the QFontInfo constructor with a QFont creates a font
info object for a screen-compatible font, i.e. the font cannot be
a printer font. If the font is changed later, the font
info object is \e not updated.
@@ -2286,12 +2286,12 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
inaccurate. Printer fonts are not always accessible so the nearest
screen font is used if a printer font is supplied.)
- \o QWidget::fontInfo() returns the font info for a widget's font.
+ \li QWidget::fontInfo() returns the font info for a widget's font.
This is equivalent to calling QFontInfo(widget->font()). If the
widget's font is changed later, the font info object is \e not
updated.
- \o QPainter::fontInfo() returns the font info for a painter's
+ \li QPainter::fontInfo() returns the font info for a painter's
current font. If the painter's font is changed later, the font
info object is \e not updated.
\endlist
@@ -2715,18 +2715,22 @@ QFontEngine *QFontCache::findEngine(const Key &key)
EngineCache::Iterator it = engineCache.find(key),
end = engineCache.end();
if (it == end) return 0;
-
// found... update the hitcount and timestamp
- it.value().hits++;
- it.value().timestamp = ++current_timestamp;
+ updateHitCountAndTimeStamp(it.value());
+
+ return it.value().data;
+}
+
+void QFontCache::updateHitCountAndTimeStamp(Engine &value)
+{
+ value.hits++;
+ value.timestamp = ++current_timestamp;
FC_DEBUG("QFontCache: found font engine\n"
" %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
- it.value().data, it.value().timestamp, it.value().hits,
- it.value().data->ref.load(), it.value().data->cache_count,
- it.value().data->name());
-
- return it.value().data;
+ value.data, value.timestamp, value.hits,
+ value.data->ref.load(), value.data->cache_count,
+ value.data->name());
}
void QFontCache::removeEngine(QFontEngine *engine)
@@ -2743,14 +2747,17 @@ void QFontCache::removeEngine(QFontEngine *engine)
}
}
-void QFontCache::insertEngine(const Key &key, QFontEngine *engine)
+void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
{
FC_DEBUG("QFontCache: inserting new engine %p", engine);
Engine data(engine);
data.timestamp = ++current_timestamp;
- engineCache.insert(key, data);
+ if (insertMulti)
+ engineCache.insertMulti(key, data);
+ else
+ engineCache.insert(key, data);
// only increase the cost if this is the first time we insert the engine
if (engine->cache_count == 0)
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d10249201a..06cf787880 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -242,9 +242,10 @@ public:
EngineCache engineCache;
QFontEngine *findEngine(const Key &key);
- void insertEngine(const Key &key, QFontEngine *engine);
- void removeEngine(QFontEngine *engine);
+ void updateHitCountAndTimeStamp(Engine &value);
+ void insertEngine(const Key &key, QFontEngine *engine, bool insertMulti = false);
+ void removeEngine(QFontEngine *engine);
private:
void increaseCost(uint cost);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7fa486e1ee..468d029cf2 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2244,7 +2244,7 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
Currently only TrueType fonts and TrueType font collections are supported.
- \bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
+ \b{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
currently not supported.
\sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 14e2dba364..8880eb7cb3 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -877,7 +877,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
if (err != FT_Err_Ok)
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- if (!set || set->outline_drawing || fetchMetricsOnly)
+ if ((!set || set->outline_drawing) && fetchMetricsOnly)
return 0;
FT_GlyphSlot slot = face->glyph;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index cf9c26f2a4..44464ee788 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -85,6 +85,7 @@ struct QGlyphLayout;
class Q_GUI_EXPORT QFontEngine : public QObject
{
+ Q_OBJECT
public:
enum Type {
Box,
@@ -343,6 +344,7 @@ private:
class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
{
+ Q_OBJECT
public:
explicit QFontEngineMulti(int engineCount);
~QFontEngineMulti();
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 33657367fa..48679824a4 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -46,8 +46,10 @@
#include <QtCore/QDir>
#include <QtCore/QBuffer>
-#include <QtGui/QPlatformFontDatabase>
#include <QtGui/private/qpaintengine_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformFontDatabase>
+#include <QtGui/QPlatformIntegration>
QT_BEGIN_NAMESPACE
@@ -662,6 +664,20 @@ void QPAGenerator::writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value
QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QStringList &fallbacks)
: QFontEngineMulti(fallbacks.size() + 1),
fallbackFamilies(fallbacks), script(_script)
+ , fallbacksQueried(true)
+{
+ init(fe);
+}
+
+QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script)
+ : QFontEngineMulti(2)
+ , script(_script)
+ , fallbacksQueried(false)
+{
+ init(fe);
+}
+
+void QFontEngineMultiQPA::init(QFontEngine *fe)
{
Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
engines[0] = fe;
@@ -672,18 +688,73 @@ QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QSt
void QFontEngineMultiQPA::loadEngine(int at)
{
+ bool canLoadFallbackEngine = true;
+ if (!fallbacksQueried) {
+ // Original FontEngine to restore after the fill.
+ QFontEngine *fe = engines[0];
+ fallbackFamilies = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(fe->fontDef.family, QFont::Style(fe->fontDef.style)
+ , QFont::AnyStyle, QUnicodeTables::Script(script));
+ if (fallbackFamilies.size() > 1) {
+ engines.fill(0, fallbackFamilies.size() + 1);
+ engines[0] = fe;
+ } else {
+ // Turns out we lied about having any fallback at all.
+ canLoadFallbackEngine = false;
+ engines[1] = fe;
+ }
+ fallbacksQueried = true;
+ }
Q_ASSERT(at < engines.size());
Q_ASSERT(engines.at(at) == 0);
-
QFontDef request = fontDef;
- request.styleStrategy |= QFont::NoFontMerging;
- request.family = fallbackFamilies.at(at-1);
- engines[at] = QFontDatabase::findFont(script,
- /*fontprivate*/0,
- request, false);
+ if (canLoadFallbackEngine) {
+ request.styleStrategy |= QFont::NoFontMerging;
+ request.family = fallbackFamilies.at(at-1);
+ engines[at] = QFontDatabase::findFont(script,
+ /*fontprivate = */0,
+ request, /*multi = */false);
+ }
Q_ASSERT(engines[at]);
engines[at]->ref.ref();
engines[at]->fontDef = request;
}
+/*
+ This is used indirectly by QtWebKit when using QTextLayout::setRawFont
+
+ The purpose of this is to provide the necessary font fallbacks when drawing complex
+ text. Since QtWebKit ends up repeatedly creating QTextLayout instances and passing them
+ the same raw font over and over again, we want to cache the corresponding multi font engine
+ as it may contain fallback font engines already.
+*/
+QFontEngine* QFontEngineMultiQPA::createMultiFontEngine(QFontEngine *fe, int script)
+{
+ QFontEngine *engine = 0;
+ QFontCache::Key key(fe->fontDef, script, /*multi = */true);
+ QFontCache *fc = QFontCache::instance();
+ // We can't rely on the fontDef (and hence the cache Key)
+ // alone to distinguish webfonts, since these should not be
+ // accidentally shared, even if the resulting fontcache key
+ // is strictly identical. See:
+ // http://www.w3.org/TR/css3-fonts/#font-face-rule
+ const bool faceIsLocal = !fe->faceId().filename.isEmpty();
+ QFontCache::EngineCache::Iterator it = fc->engineCache.find(key),
+ end = fc->engineCache.end();
+ while (it != end && it.key() == key) {
+ QFontEngineMulti *cachedEngine = qobject_cast<QFontEngineMulti *>(it.value().data);
+ if (faceIsLocal || (cachedEngine && fe == cachedEngine->engine(0))) {
+ engine = cachedEngine;
+ fc->updateHitCountAndTimeStamp(it.value());
+ break;
+ }
+ it++;
+ }
+ if (!engine) {
+ engine = new QFontEngineMultiQPA(fe, script);
+ QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);
+ }
+ Q_ASSERT(engine);
+ return engine;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpa_p.h
index ed2e071ac2..16991ad2ca 100644
--- a/src/gui/text/qfontengine_qpa_p.h
+++ b/src/gui/text/qfontengine_qpa_p.h
@@ -249,13 +249,18 @@ public:
QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks);
void loadEngine(int at);
+ static QFontEngine* createMultiFontEngine(QFontEngine *fe, int script);
int fallbackFamilyCount() const { return fallbackFamilies.size(); }
QString fallbackFamilyAt(int at) const { return fallbackFamilies.at(at); }
private:
+ QFontEngineMultiQPA(QFontEngine *fe, int script);
+ void init(QFontEngine *fe);
+
QStringList fallbackFamilies;
int script;
+ bool fallbacksQueried;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 283494e316..7209fbdfc3 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -76,7 +76,7 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
QFontMetrics object:
\list 1
- \o Calling the QFontMetrics constructor with a QFont creates a
+ \li Calling the QFontMetrics constructor with a QFont creates a
font metrics object for a screen-compatible font, i.e. the font
cannot be a printer font. If the font is changed
later, the font metrics object is \e not updated.
@@ -85,12 +85,12 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
inaccurate. Printer fonts are not always accessible so the nearest
screen font is used if a printer font is supplied.)
- \o QWidget::fontMetrics() returns the font metrics for a widget's
+ \li QWidget::fontMetrics() returns the font metrics for a widget's
font. This is equivalent to QFontMetrics(widget->font()). If the
widget's font is changed later, the font metrics object is \e not
updated.
- \o QPainter::fontMetrics() returns the font metrics for a
+ \li QPainter::fontMetrics() returns the font metrics for a
painter's current font. If the painter's font is changed later, the
font metrics object is \e not updated.
\endlist
@@ -713,20 +713,20 @@ QRect QFontMetrics::boundingRect(QChar ch) const
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::AlignLeft aligns to the left border, except for
+ \li Qt::AlignLeft aligns to the left border, except for
Arabic and Hebrew where it aligns to the right.
- \o Qt::AlignRight aligns to the right border, except for
+ \li Qt::AlignRight aligns to the right border, except for
Arabic and Hebrew where it aligns to the left.
- \o Qt::AlignJustify produces justified text.
- \o Qt::AlignHCenter aligns horizontally centered.
- \o Qt::AlignTop aligns to the top border.
- \o Qt::AlignBottom aligns to the bottom border.
- \o Qt::AlignVCenter aligns vertically centered
- \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
- \o Qt::TextSingleLine ignores newline characters in the text.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordWrap breaks the text to fit the rectangle.
+ \li Qt::AlignJustify produces justified text.
+ \li Qt::AlignHCenter aligns horizontally centered.
+ \li Qt::AlignTop aligns to the top border.
+ \li Qt::AlignBottom aligns to the bottom border.
+ \li Qt::AlignVCenter aligns vertically centered
+ \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
+ \li Qt::TextSingleLine ignores newline characters in the text.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
@@ -780,10 +780,10 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::TextSingleLine ignores newline characters.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordBreak breaks the text to fit the rectangle.
+ \li Qt::TextSingleLine ignores newline characters.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordBreak breaks the text to fit the rectangle.
\endlist
If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is
@@ -1490,20 +1490,20 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::AlignLeft aligns to the left border, except for
+ \li Qt::AlignLeft aligns to the left border, except for
Arabic and Hebrew where it aligns to the right.
- \o Qt::AlignRight aligns to the right border, except for
+ \li Qt::AlignRight aligns to the right border, except for
Arabic and Hebrew where it aligns to the left.
- \o Qt::AlignJustify produces justified text.
- \o Qt::AlignHCenter aligns horizontally centered.
- \o Qt::AlignTop aligns to the top border.
- \o Qt::AlignBottom aligns to the bottom border.
- \o Qt::AlignVCenter aligns vertically centered
- \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
- \o Qt::TextSingleLine ignores newline characters in the text.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordWrap breaks the text to fit the rectangle.
+ \li Qt::AlignJustify produces justified text.
+ \li Qt::AlignHCenter aligns horizontally centered.
+ \li Qt::AlignTop aligns to the top border.
+ \li Qt::AlignBottom aligns to the bottom border.
+ \li Qt::AlignVCenter aligns vertically centered
+ \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
+ \li Qt::TextSingleLine ignores newline characters in the text.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
@@ -1517,9 +1517,9 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
If Qt::TextExpandTabs is set in \a flags, the following behavior is
used to interpret tab characters in the text:
\list
- \o If \a tabArray is non-null, it specifies a 0-terminated sequence of
+ \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
pixel-positions for tabs in the text.
- \o If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
+ \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
\endlist
Note that the bounding rectangle may extend to the left of (0, 0),
@@ -1559,10 +1559,10 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::TextSingleLine ignores newline characters.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordBreak breaks the text to fit the rectangle.
+ \li Qt::TextSingleLine ignores newline characters.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordBreak breaks the text to fit the rectangle.
\endlist
These flags are defined in \l{Qt::TextFlags}.
@@ -1570,9 +1570,9 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
If Qt::TextExpandTabs is set in \a flags, the following behavior is
used to interpret tab characters in the text:
\list
- \o If \a tabArray is non-null, it specifies a 0-terminated sequence of
+ \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
pixel-positions for tabs in the text.
- \o If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
+ \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
\endlist
Newline characters are processed as line breaks.
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 79793d5845..9fbeef4685 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -86,13 +86,13 @@ QT_BEGIN_NAMESPACE
QRawFont can be constructed in a number of ways:
\list
- \o It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
+ \li It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
used to render each portion of the text.
- \o It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
+ \li It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
will return a QRawFont object representing the font that will be selected as response to
the QFont query and the selected writing system.
- \o It can be constructed by passing a file name or QByteArray directly to the QRawFont
+ \li It can be constructed by passing a file name or QByteArray directly to the QRawFont
constructor, or by calling loadFromFile() or loadFromData(). In this case, the
font will not be registered in QFontDatabase, and it will not be available as part of
regular font selection.
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index 5cd996e705..bc5f6621c8 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -138,6 +138,7 @@ public:
private:
friend class QRawFontPrivate;
friend class QTextLayout;
+ friend class QTextEngine;
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index cbffc4315f..02fd921fac 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -950,15 +950,15 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{
document with the cursor:
\list
- \i Lists are ordered sequences of block elements that are decorated with
+ \li Lists are ordered sequences of block elements that are decorated with
bullet points or symbols. These are inserted in a specified format
with insertList().
- \i Tables are inserted with the insertTable() function, and can be
+ \li Tables are inserted with the insertTable() function, and can be
given an optional format. These contain an array of cells that can
be traversed using the cursor.
- \i Inline images are inserted with insertImage(). The image to be
+ \li Inline images are inserted with insertImage(). The image to be
used can be specified in an image format, or by name.
- \i Frames are inserted by calling insertFrame() with a specified format.
+ \li Frames are inserted by calling insertFrame() with a specified format.
\endlist
Actions can be grouped (i.e. treated as a single action for
@@ -1621,7 +1621,7 @@ void QTextCursor::selectedTableCells(int *firstRow, int *numRows, int *firstColu
/*!
Clears the current selection by setting the anchor to the cursor position.
- Note that it does \bold{not} delete the text of the selection.
+ Note that it does \b{not} delete the text of the selection.
\sa removeSelectedText() hasSelection()
*/
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 1fad064b5c..a8991d5428 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -261,14 +261,14 @@ QTextCodec *Qt::codecForHtml(const QByteArray &ba)
system. The following are the undo/redo operations of a QTextDocument:
\list
- \o Insertion or removal of characters. A sequence of insertions or removals
+ \li Insertion or removal of characters. A sequence of insertions or removals
within the same text block are regarded as a single undo/redo operation.
- \o Insertion or removal of text blocks. Sequences of insertion or removals
+ \li Insertion or removal of text blocks. Sequences of insertion or removals
in a single operation (e.g., by selecting and then deleting text) are
regarded as a single undo/redo operation.
- \o Text character format changes.
- \o Text block format changes.
- \o Text block group format changes.
+ \li Text character format changes.
+ \li Text block format changes.
+ \li Text block group format changes.
\endlist
\sa QTextCursor, QTextEdit, \link richtext.html Rich Text Processing\endlink , {Text Object Example}
@@ -887,7 +887,7 @@ QChar QTextDocument::characterAt(int pos) const
The style sheet needs to be compliant to CSS 2.1 syntax.
- \bold{Note:} Changing the default style sheet does not have any effect to the existing content
+ \b{Note:} Changing the default style sheet does not have any effect to the existing content
of the document.
\sa {Supported HTML Subset}
@@ -1169,7 +1169,7 @@ void QTextDocument::setPlainText(const QString &text)
The HTML formatting is respected as much as possible; for example,
"<b>bold</b> text" will produce text where the first word has a font
- weight that gives it a bold appearance: "\bold{bold} text".
+ weight that gives it a bold appearance: "\b{bold} text".
\note It is the responsibility of the caller to make sure that the
text is correctly decoded when a QString containing HTML is created
diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp
index d43a61866d..b0bbeb7a47 100644
--- a/src/gui/text/qtextdocumentwriter.cpp
+++ b/src/gui/text/qtextdocumentwriter.cpp
@@ -345,10 +345,10 @@ QTextCodec *QTextDocumentWriter::codec() const
By default, Qt can write the following formats:
\table
- \header \o Format \o Description
- \row \o plaintext \o Plain text
- \row \o HTML \o HyperText Markup Language
- \row \o ODF \o OpenDocument Format
+ \header \li Format \li Description
+ \row \li plaintext \li Plain text
+ \row \li HTML \li HyperText Markup Language
+ \row \li ODF \li OpenDocument Format
\endtable
\sa setFormat()
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c63f0fede8..0460db14d5 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -53,13 +53,18 @@
#include "qstring.h"
#include <private/qunicodetables_p.h>
#include "qtextdocument_p.h"
+#include "qrawfont.h"
+#include "qrawfont_p.h"
#include <qguiapplication.h>
#include <qinputmethod.h>
#include <stdlib.h>
+#include "qfontengine_qpa_p.h"
QT_BEGIN_NAMESPACE
+static const float smallCapsFraction = 0.7;
+
namespace {
// Helper class used in QTextEngine::itemize
// keep it out here to allow us to keep supporting various compilers.
@@ -900,13 +905,25 @@ void QTextEngine::shapeText(int item) const
return;
QGlyphLayout glyphs = shapedGlyphs(&si);
- QFont font = this->font(si);
- bool letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
- QFixed letterSpacing = font.d->letterSpacing;
- QFixed wordSpacing = font.d->wordSpacing;
+ bool letterSpacingIsAbsolute;
+ QFixed letterSpacing, wordSpacing;
+#ifndef QT_NO_RAWFONT
+ if (useRawFont) {
+ QTextCharFormat f = format(&si);
+ wordSpacing = QFixed::fromReal(f.fontWordSpacing());
+ letterSpacing = QFixed::fromReal(f.fontLetterSpacing());
+ letterSpacingIsAbsolute = true;
+ } else
+#endif
+ {
+ QFont font = this->font(si);
+ letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
+ letterSpacing = font.d->letterSpacing;
+ wordSpacing = font.d->wordSpacing;
- if (letterSpacingIsAbsolute && letterSpacing.value())
- letterSpacing *= font.d->dpi / qt_defaultDpiY();
+ if (letterSpacingIsAbsolute && letterSpacing.value())
+ letterSpacing *= font.d->dpi / qt_defaultDpiY();
+ }
if (letterSpacing != 0) {
for (int i = 1; i < si.num_glyphs; ++i) {
@@ -973,7 +990,14 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
- bool kerningEnabled = this->font(si).d->kerning;
+ bool kerningEnabled;
+#ifndef QT_NO_RAWFONT
+ if (useRawFont) {
+ QTextCharFormat f = format(&si);
+ kerningEnabled = f.fontKerning();
+ } else
+#endif
+ kerningEnabled = this->font(si).d->kerning;
HB_ShaperItem entire_shaper_item;
qMemSet(&entire_shaper_item, 0, sizeof(entire_shaper_item));
@@ -1159,6 +1183,9 @@ static void init(QTextEngine *e)
e->underlinePositions = 0;
e->specialData = 0;
e->stackEngine = false;
+#ifndef QT_NO_RAWFONT
+ e->useRawFont = false;
+#endif
}
QTextEngine::QTextEngine()
@@ -1401,7 +1428,21 @@ void QTextEngine::itemize() const
++it;
}
} else {
- itemizer.generate(0, length, static_cast<QFont::Capitalization> (fnt.d->capital));
+#ifndef QT_NO_RAWFONT
+ if (useRawFont && specialData) {
+ int lastIndex = 0;
+ for (int i = 0; i < specialData->addFormats.size(); ++i) {
+ const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
+ if (range.format.fontCapitalization()) {
+ itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
+ itemizer.generate(range.start, range.length, range.format.fontCapitalization());
+ lastIndex = range.start + range.length;
+ }
+ }
+ itemizer.generate(lastIndex, length - lastIndex, QFont::MixedCase);
+ } else
+#endif
+ itemizer.generate(0, length, static_cast<QFont::Capitalization> (fnt.d->capital));
}
addRequiredBoundaries();
@@ -1663,59 +1704,85 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
int script = si.analysis.script;
QFont font = fnt;
- if (hasFormats()) {
- if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+#ifndef QT_NO_RAWFONT
+ if (useRawFont && rawFont.isValid()) {
+ if (feCache.prevFontEngine && feCache.prevFontEngine->type() == QFontEngine::Multi && feCache.prevScript == script) {
engine = feCache.prevFontEngine;
- scaledEngine = feCache.prevScaledFontEngine;
} else {
- QTextCharFormat f = format(&si);
- font = f.font();
-
- if (block.docHandle() && block.docHandle()->layout()) {
- // Make sure we get the right dpi on printers
- QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
- if (pdev)
- font = QFont(font, pdev);
- } else {
- font = font.resolve(fnt);
- }
- engine = font.d->engineForScript(script);
- QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
- if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
- if (font.pointSize() != -1)
- font.setPointSize((font.pointSize() * 2) / 3);
- else
- font.setPixelSize((font.pixelSize() * 2) / 3);
- scaledEngine = font.d->engineForScript(script);
- }
+ engine = QFontEngineMultiQPA::createMultiFontEngine(rawFont.d->fontEngine, script);
feCache.prevFontEngine = engine;
- if (engine)
- engine->ref.ref();
- feCache.prevScaledFontEngine = scaledEngine;
- if (scaledEngine)
- scaledEngine->ref.ref();
feCache.prevScript = script;
- feCache.prevPosition = si.position;
- feCache.prevLength = length(&si);
+ engine->ref.ref();
+ if (feCache.prevScaledFontEngine)
+ releaseCachedFontEngine(feCache.prevScaledFontEngine);
}
- } else {
- if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
- engine = feCache.prevFontEngine;
- else {
- engine = font.d->engineForScript(script);
- feCache.prevFontEngine = engine;
- if (engine)
- engine->ref.ref();
- feCache.prevScript = script;
- feCache.prevPosition = -1;
- feCache.prevLength = -1;
- feCache.prevScaledFontEngine = 0;
+ if (si.analysis.flags & QFont::SmallCaps) {
+ if (feCache.prevScaledFontEngine) {
+ scaledEngine = feCache.prevScaledFontEngine;
+ } else {
+ QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize());
+ scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script);
+ scaledEngine->ref.ref();
+ feCache.prevScaledFontEngine = scaledEngine;
+ }
+ }
+ } else
+#endif
+ {
+ if (hasFormats()) {
+ if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+ engine = feCache.prevFontEngine;
+ scaledEngine = feCache.prevScaledFontEngine;
+ } else {
+ QTextCharFormat f = format(&si);
+ font = f.font();
+
+ if (block.docHandle() && block.docHandle()->layout()) {
+ // Make sure we get the right dpi on printers
+ QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
+ if (pdev)
+ font = QFont(font, pdev);
+ } else {
+ font = font.resolve(fnt);
+ }
+ engine = font.d->engineForScript(script);
+ QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
+ if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
+ if (font.pointSize() != -1)
+ font.setPointSize((font.pointSize() * 2) / 3);
+ else
+ font.setPixelSize((font.pixelSize() * 2) / 3);
+ scaledEngine = font.d->engineForScript(script);
+ }
+ feCache.prevFontEngine = engine;
+ if (engine)
+ engine->ref.ref();
+ feCache.prevScaledFontEngine = scaledEngine;
+ if (scaledEngine)
+ scaledEngine->ref.ref();
+ feCache.prevScript = script;
+ feCache.prevPosition = si.position;
+ feCache.prevLength = length(&si);
+ }
+ } else {
+ if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
+ engine = feCache.prevFontEngine;
+ else {
+ engine = font.d->engineForScript(script);
+ feCache.prevFontEngine = engine;
+ if (engine)
+ engine->ref.ref();
+ feCache.prevScript = script;
+ feCache.prevPosition = -1;
+ feCache.prevLength = -1;
+ feCache.prevScaledFontEngine = 0;
+ }
}
- }
- if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
- QFontPrivate *p = font.d->smallCapsFontPrivate();
- scaledEngine = p->engineForScript(script);
+ if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
+ QFontPrivate *p = font.d->smallCapsFontPrivate();
+ scaledEngine = p->engineForScript(script);
+ }
}
if (ascent) {
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index b29f626b68..6f1fd713f1 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -581,7 +581,10 @@ public:
mutable FontEngineCache feCache;
QString text;
- QFont fnt;
+ mutable QFont fnt;
+#ifndef QT_NO_RAWFONT
+ QRawFont rawFont;
+#endif
QTextBlock block;
QTextOption option;
@@ -594,6 +597,9 @@ public:
uint stackEngine : 1;
uint forceJustification : 1;
uint visualMovement : 1;
+#ifndef QT_NO_RAWFONT
+ uint useRawFont : 1;
+#endif
int *underlinePositions;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 943caea644..d5b05a8957 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -361,6 +361,22 @@ QTextLayout::~QTextLayout()
delete d;
}
+#ifndef QT_NO_RAWFONT
+/*!
+ \internal
+ Sets a raw font, to be used with QTextLayout::glyphRuns.
+ Note that this only supports the needs of WebKit.
+ Use of this function with e.g. QTextLayout::draw will result
+ in undefined behaviour.
+*/
+void QTextLayout::setRawFont(const QRawFont &rawFont)
+{
+ d->rawFont = rawFont;
+ d->useRawFont = true;
+ d->resetFontEngineCache();
+}
+#endif
+
/*!
Sets the layout's font to the given \a font. The layout is
invalidated and must be laid out again.
@@ -370,6 +386,9 @@ QTextLayout::~QTextLayout()
void QTextLayout::setFont(const QFont &font)
{
d->fnt = font;
+#ifndef QT_NO_RAWFONT
+ d->useRawFont = false;
+#endif
d->resetFontEngineCache();
}
@@ -2204,15 +2223,17 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
continue;
}
- QFont font = eng->font(si);
-
+ QFont font;
QGlyphRun::GlyphRunFlags flags;
- if (font.overline())
- flags |= QGlyphRun::Overline;
- if (font.underline())
- flags |= QGlyphRun::Underline;
- if (font.strikeOut())
- flags |= QGlyphRun::StrikeOut;
+ if (!eng->useRawFont) {
+ font = eng->font(si);
+ if (font.overline())
+ flags |= QGlyphRun::Overline;
+ if (font.underline())
+ flags |= QGlyphRun::Underline;
+ if (font.strikeOut())
+ flags |= QGlyphRun::StrikeOut;
+ }
bool rtl = false;
if (si.analysis.bidiLevel % 2) {
@@ -2264,7 +2285,8 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
iterator.getSelectionBounds(&x, &width);
if (glyphLayout.numGlyphs > 0) {
- QFontEngine *mainFontEngine = font.d->engineForScript(si.analysis.script);
+ QFontEngine *mainFontEngine = eng->fontEngine(si);
+
if (mainFontEngine->type() == QFontEngine::Multi) {
QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
int end = rtl ? glyphLayout.numGlyphs : 0;
@@ -2331,6 +2353,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
*/
void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatRange *selection) const
{
+#ifndef QT_NO_RAWFONT
+ // Not intended to work with rawfont
+ Q_ASSERT(!eng->useRawFont);
+#endif
const QScriptLine &line = eng->lines[index];
QPen pen = p->pen();
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index a3bc79dc52..2c38973371 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE
class QTextEngine;
class QFont;
+#ifndef QT_NO_RAWFONT
+class QRawFont;
+#endif
class QRect;
class QRegion;
class QTextFormat;
@@ -114,6 +117,10 @@ public:
void setFont(const QFont &f);
QFont font() const;
+#ifndef QT_NO_RAWFONT
+ void setRawFont(const QRawFont &rawFont);
+#endif
+
void setText(const QString& string);
QString text() const;
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index 5a642e90ef..c3c71bc021 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -107,7 +107,7 @@ public:
Returns true if the list has no items; otherwise returns false.
- \bold{Note:} Empty lists are automatically deleted by the QTextDocument that owns
+ \b{Note:} Empty lists are automatically deleted by the QTextDocument that owns
them.
\sa count()
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index 12af933fd0..65bc8fde1e 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -541,22 +541,22 @@ void QTextTablePrivate::update() const
\table 80%
\row
- \o \inlineimage texttable-split.png Original Table
- \o Suppose we have a 2x3 table of names and addresses. To merge both
+ \li \inlineimage texttable-split.png Original Table
+ \li Suppose we have a 2x3 table of names and addresses. To merge both
columns in the first row we invoke mergeCells() with \a row = 0,
\a column = 0, \a numRows = 1 and \a numColumns = 2.
\snippet doc/src/snippets/textdocument-texttable/main.cpp 0
\row
- \o \inlineimage texttable-merge.png
- \o This gives us the following table. To split the first row of the table
+ \li \inlineimage texttable-merge.png
+ \li This gives us the following table. To split the first row of the table
back into two cells, we invoke the splitCell() function with \a numRows
and \a numCols = 1.
\snippet doc/src/snippets/textdocument-texttable/main.cpp 1
\row
- \o \inlineimage texttable-split.png Split Table
- \o This results in the original table.
+ \li \inlineimage texttable-split.png Split Table
+ \li This results in the original table.
\endtable
\sa QTextTableFormat
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 02552f5a53..ce16785d1d 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -82,18 +82,18 @@ QT_BEGIN_NAMESPACE
\list
- \i For a line edit that accepts integers from 10 to 1000 inclusive,
+ \li For a line edit that accepts integers from 10 to 1000 inclusive,
42 and 123 are \l Acceptable, the empty string and 5 are \l
Intermediate, and "asdf" and 1114 is \l Invalid.
- \i For an editable combobox that accepts URLs, any well-formed URL
+ \li For an editable combobox that accepts URLs, any well-formed URL
is \l Acceptable, "http://example.com/," is \l Intermediate
(it might be a cut and paste action that accidentally took in a
comma at the end), the empty string is \l Intermediate (the user
might select and delete all of the text in preparation for entering
a new URL) and "http:///./" is \l Invalid.
- \i For a spin box that accepts lengths, "11cm" and "1in" are \l
+ \li For a spin box that accepts lengths, "11cm" and "1in" are \l
Acceptable, "11" and the empty string are \l Intermediate, and
"http://example.com" and "hour" are \l Invalid.
@@ -801,13 +801,13 @@ QDoubleValidator::Notation QDoubleValidator::notation() const
When QRegExpValidator determines whether a string is \l Acceptable
or not, the regexp is treated as if it begins with the start of string
- assertion (\bold{^}) and ends with the end of string assertion
- (\bold{$}); the match is against the entire input string, or from
+ assertion (\b{^}) and ends with the end of string assertion
+ (\b{$}); the match is against the entire input string, or from
the given position if a start position greater than zero is given.
If a string is a prefix of an \l Acceptable string, it is considered
\l Intermediate. For example, "" and "A" are \l Intermediate for the
- regexp \bold{[A-Z][0-9]} (whereas "_" would be \l Invalid).
+ regexp \b{[A-Z][0-9]} (whereas "_" would be \l Invalid).
For a brief introduction to Qt's regexp engine, see \l QRegExp.
@@ -837,7 +837,7 @@ QRegExpValidator::QRegExpValidator(QObject *parent)
accepts all strings that match the regular expression \a rx.
The match is made against the entire string; e.g. if the regexp is
- \bold{[A-Fa-f0-9]+} it will be treated as \bold{^[A-Fa-f0-9]+$}.
+ \b{[A-Fa-f0-9]+} it will be treated as \b{^[A-Fa-f0-9]+$}.
*/
QRegExpValidator::QRegExpValidator(const QRegExp& rx, QObject *parent)
@@ -862,7 +862,7 @@ QRegExpValidator::~QRegExpValidator()
The \a pos parameter is set to the length of the \a input parameter.
- For example, if the regular expression is \bold{\\w\\d\\d}
+ For example, if the regular expression is \b{\\w\\d\\d}
(word-character, digit, digit) then "A57" is \l Acceptable,
"E5" is \l Intermediate, and "+9" is \l Invalid.
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index e4ea62f093..3991bffa47 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -646,7 +646,7 @@ void QHttpNetworkConnectionChannel::allDone()
Q_ASSERT(reply);
if (!reply) {
- qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.nokia.com/";
+ qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt-project.org/";
return;
}
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 740e54b833..60c28274c6 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -451,12 +451,12 @@ QNetworkProxyFactory *QNetworkAccessManager::proxyFactory() const
For example, a proxy factory could apply the following rules:
\list
- \o if the target address is in the local network (for example,
+ \li if the target address is in the local network (for example,
if the hostname contains no dots or if it's an IP address in
the organization's range), return QNetworkProxy::NoProxy
- \o if the request is FTP, return an FTP proxy
- \o if the request is HTTP or HTTPS, then return an HTTP proxy
- \o otherwise, return a SOCKSv5 proxy server
+ \li if the request is FTP, return an FTP proxy
+ \li if the request is HTTP or HTTPS, then return an HTTP proxy
+ \li otherwise, return a SOCKSv5 proxy server
\endlist
The lifetime of the object \a factory will be managed by
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 88b021d780..0dbfdb2f0c 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -409,7 +409,7 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi
// quoted-pair = "\" CHAR
// If it is NAME=VALUE, retain the value as is
- // refer to http://bugreports.qt.nokia.com/browse/QTBUG-17746
+ // refer to http://bugreports.qt-project.org/browse/QTBUG-17746
if (isNameValue)
second += '"';
++i;
@@ -1060,7 +1060,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
*/
void QNetworkCookie::normalize(const QUrl &url)
{
- // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
+ // don't do path checking. See http://bugreports.qt-project.org/browse/QTBUG-5815
if (d->path.isEmpty()) {
QString pathAndFileName = url.path();
QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index a4413cda95..2124395de3 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -607,12 +607,14 @@ void QNetworkReplyHttpImplPrivate::postRequest()
if (synchronous) {
// A synchronous HTTP request uses its own thread
thread = new QThread();
+ thread->setObjectName(QStringLiteral("httpReply"));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
} else if (!managerPrivate->httpThread) {
// We use the manager-global thread.
// At some point we could switch to having multiple threads if it makes sense.
managerPrivate->httpThread = new QThread();
+ managerPrivate->httpThread->setObjectName(QStringLiteral("httpThread"));
QObject::connect(managerPrivate->httpThread, SIGNAL(finished()), managerPrivate->httpThread, SLOT(deleteLater()));
managerPrivate->httpThread->start();
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index 25bf21e7b9..d152adca92 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -70,6 +70,8 @@ void QNetworkConfigurationManagerPrivate::initialize()
{
//Two stage construction, because we only want to do this heavyweight work for the winner of the Q_GLOBAL_STATIC race.
bearerThread = new QThread();
+ bearerThread->setObjectName(QStringLiteral("bearerThread"));
+
bearerThread->moveToThread(QCoreApplicationPrivate::mainThread()); // because cleanup() is called in main thread context.
moveToThread(bearerThread);
bearerThread->start();
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 037a7fdbf3..0aa843f393 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -424,37 +424,37 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
\table
\header
- \o BearerType
- \o Value
+ \li BearerType
+ \li Value
\row
- \o BearerUnknown
- \o
- \o The session is based on an unknown or unspecified bearer type. The value of the
+ \li BearerUnknown
+ \li
+ \li The session is based on an unknown or unspecified bearer type. The value of the
string returned describes the bearer type.
\row
- \o BearerEthernet
- \o Ethernet
+ \li BearerEthernet
+ \li Ethernet
\row
- \o BearerWLAN
- \o WLAN
+ \li BearerWLAN
+ \li WLAN
\row
- \o Bearer2G
- \o 2G
+ \li Bearer2G
+ \li 2G
\row
- \o BearerCDMA2000
- \o CDMA2000
+ \li BearerCDMA2000
+ \li CDMA2000
\row
- \o BearerWCDMA
- \o WCDMA
+ \li BearerWCDMA
+ \li WCDMA
\row
- \o BearerHSPA
- \o HSPA
+ \li BearerHSPA
+ \li HSPA
\row
- \o BearerBluetooth
- \o Bluetooth
+ \li BearerBluetooth
+ \li Bluetooth
\row
- \o BearerWiMAX
- \o WiMAX
+ \li BearerWiMAX
+ \li WiMAX
\endtable
This function returns an empty string if this is an invalid configuration, a network
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index 3f8cabe26e..ccf794633d 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -455,10 +455,10 @@ QString QNetworkSession::errorString() const
\table
\header
- \o Key \o Description
+ \li Key \li Description
\row
- \o ActiveConfiguration
- \o If the session \l isOpen() this property returns the identifier of the
+ \li ActiveConfiguration
+ \li If the session \l isOpen() this property returns the identifier of the
QNetworkConfiguration that is used by this session; otherwise an empty string.
The main purpose of this key is to determine which Internet access point is used
@@ -479,8 +479,8 @@ QString QNetworkSession::errorString() const
}
\endcode
\row
- \o UserChoiceConfiguration
- \o If the session \l isOpen() and is bound to a QNetworkConfiguration of type
+ \li UserChoiceConfiguration
+ \li If the session \l isOpen() and is bound to a QNetworkConfiguration of type
UserChoice, this property returns the identifier of the QNetworkConfiguration that the
configuration resolved to when \l open() was called; otherwise an empty string.
@@ -492,14 +492,14 @@ QString QNetworkSession::errorString() const
whereas \e ActiveConfiguration always returns identifiers to
\l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
\row
- \o ConnectInBackground
- \o Setting this property to \e true before calling \l open() implies that the connection attempt
+ \li ConnectInBackground
+ \li Setting this property to \e true before calling \l open() implies that the connection attempt
is made but if no connection can be established, the user is not connsulted and asked to select
a suitable connection. This property is not set by default and support for it depends on the platform.
\row
- \o AutoCloseSessionTimeout
- \o If the session requires polling to keep its state up to date, this property holds
+ \li AutoCloseSessionTimeout
+ \li If the session requires polling to keep its state up to date, this property holds
the timeout in milliseconds before the session will automatically close. If the
value of this property is -1 the session will not automatically close. This property
is set to -1 by default.
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index adc72bbcbb..a5508af31f 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -29,6 +29,7 @@ unix:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnet
win32: {
HEADERS += kernel/qnetworkinterface_win_p.h
SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp
+ LIBS += -ldnsapi
}
integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index b14fbf8c30..eef2a7fa76 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -80,9 +80,9 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
QAuthenticator supports the following authentication methods:
\list
- \o Basic
- \o NTLM version 2
- \o Digest-MD5
+ \li Basic
+ \li NTLM version 2
+ \li Digest-MD5
\endlist
\section1 Options
@@ -104,8 +104,8 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
\section2 Basic
\table
- \header \o Option \o Direction \o Description
- \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
+ \header \li Option \li Direction \li Description
+ \row \li \tt{realm} \li Incoming \li Contains the realm of the authentication, the same as realm()
\endtable
The Basic authentication mechanism supports no outgoing options.
@@ -117,8 +117,8 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
\section2 Digest-MD5
\table
- \header \o Option \o Direction \o Description
- \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
+ \header \li Option \li Direction \li Description
+ \row \li \tt{realm} \li Incoming \li Contains the realm of the authentication, the same as realm()
\endtable
The Digest-MD5 authentication mechanism supports no outgoing options.
diff --git a/src/network/kernel/qdnslookup_win.cpp b/src/network/kernel/qdnslookup_win.cpp
index 9b2c088ee2..63f4377dfc 100644
--- a/src/network/kernel/qdnslookup_win.cpp
+++ b/src/network/kernel/qdnslookup_win.cpp
@@ -44,46 +44,18 @@
#include <qurl.h>
#include <private/qmutexpool_p.h>
-#include <private/qsystemlibrary_p.h>
+#include <private/qsystemerror_p.h>
#include <qt_windows.h>
#include <windns.h>
QT_BEGIN_NAMESPACE
-typedef DNS_STATUS (*dns_query_utf8_proto)(PCSTR,WORD,DWORD,PIP4_ARRAY,PDNS_RECORD*,PVOID*);
-static dns_query_utf8_proto local_dns_query_utf8 = 0;
-typedef void (*dns_record_list_free_proto)(PDNS_RECORD,DNS_FREE_TYPE);
-static dns_record_list_free_proto local_dns_record_list_free = 0;
-
-static void resolveLibrary()
-{
- local_dns_query_utf8 = (dns_query_utf8_proto) QSystemLibrary::resolve(QLatin1String("dnsapi"), "DnsQuery_UTF8");
- local_dns_record_list_free = (dns_record_list_free_proto) QSystemLibrary::resolve(QLatin1String("dnsapi"), "DnsRecordListFree");
-}
-
void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
{
- // Load DnsQuery_UTF8 and DnsRecordListFree on demand.
- static volatile bool triedResolve = false;
- if (!triedResolve) {
- QMutexLocker locker(QMutexPool::globalInstanceGet(&local_dns_query_utf8));
- if (!triedResolve) {
- resolveLibrary();
- triedResolve = true;
- }
- }
-
- // If DnsQuery_UTF8 or DnsRecordListFree is missing, fail.
- if (!local_dns_query_utf8 || !local_dns_record_list_free) {
- reply->error = QDnsLookup::ResolverError,
- reply->errorString = tr("Resolver functions not found");
- return;
- }
-
// Perform DNS query.
- PDNS_RECORD dns_records;
- const DNS_STATUS status = local_dns_query_utf8(requestName, requestType, DNS_QUERY_STANDARD, NULL, &dns_records, NULL);
+ PDNS_RECORD dns_records = 0;
+ const DNS_STATUS status = DnsQuery_UTF8(requestName, requestType, DNS_QUERY_STANDARD, NULL, &dns_records, NULL);
switch (status) {
case ERROR_SUCCESS:
break;
@@ -105,7 +77,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
return;
default:
reply->error = QDnsLookup::InvalidReplyError;
- reply->errorString = tr("Invalid reply received");
+ reply->errorString = QSystemError(status, QSystemError::NativeError).toString();
return;
}
@@ -172,7 +144,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
}
}
- local_dns_record_list_free(dns_records, DnsFreeRecordList);
+ DnsRecordListFree(dns_records, DnsFreeRecordList);
}
QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index dd46b8126b..230abb86aa 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -822,20 +822,20 @@ QString QHostAddress::toString() const
\list
- \o Node-local: Addresses that are only used for communicating with
+ \li Node-local: Addresses that are only used for communicating with
services on the same interface (e.g., the loopback interface "::1").
- \o Link-local: Addresses that are local to the network interface
+ \li Link-local: Addresses that are local to the network interface
(\e{link}). There is always one link-local address for each IPv6 interface
on your host. Link-local addresses ("fe80...") are generated from the MAC
address of the local network adaptor, and are not guaranteed to be unique.
- \o Site-local: Addresses that are local to the site / private network
+ \li Site-local: Addresses that are local to the site / private network
(e.g., the company intranet). Site-local addresses ("fec0...") are
usually distributed by the site router, and are not guaranteed to be
unique outside of the local site.
- \o Global: For globally routable addresses, such as public servers on the
+ \li Global: For globally routable addresses, such as public servers on the
Internet.
\endlist
@@ -1001,9 +1001,9 @@ bool QHostAddress::isInSubnet(const QPair<QHostAddress, int> &subnet) const
This function supports arguments in the form:
\list
- \o 123.123.123.123/n where n is any value between 0 and 32
- \o 123.123.123.123/255.255.255.255
- \o <ipv6-address>/n where n is any value between 0 and 128
+ \li 123.123.123.123/n where n is any value between 0 and 32
+ \li 123.123.123.123/255.255.255.255
+ \li <ipv6-address>/n where n is any value between 0 and 128
\endlist
For IP version 4, this function accepts as well missing trailing
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 0238d22eb6..0281eaf48b 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -139,35 +139,35 @@
\table
\header
- \o Proxy type
- \o Description
- \o Default capabilities
+ \li Proxy type
+ \li Description
+ \li Default capabilities
\row
- \o SOCKS 5
- \o Generic proxy for any kind of connection. Supports TCP,
+ \li SOCKS 5
+ \li Generic proxy for any kind of connection. Supports TCP,
UDP, binding to a port (incoming connections) and
authentication.
- \o TunnelingCapability, ListeningCapability,
+ \li TunnelingCapability, ListeningCapability,
UdpTunnelingCapability, HostNameLookupCapability
\row
- \o HTTP
- \o Implemented using the "CONNECT" command, supports only
+ \li HTTP
+ \li Implemented using the "CONNECT" command, supports only
outgoing TCP connections; supports authentication.
- \o TunnelingCapability, CachingCapability, HostNameLookupCapability
+ \li TunnelingCapability, CachingCapability, HostNameLookupCapability
\row
- \o Caching-only HTTP
- \o Implemented using normal HTTP commands, it is useful only
+ \li Caching-only HTTP
+ \li Implemented using normal HTTP commands, it is useful only
in the context of HTTP requests (see QNetworkAccessManager)
- \o CachingCapability, HostNameLookupCapability
+ \li CachingCapability, HostNameLookupCapability
\row
- \o Caching FTP
- \o Implemented using an FTP proxy, it is useful only in the
+ \li Caching FTP
+ \li Implemented using an FTP proxy, it is useful only in the
context of FTP requests (see QNetworkAccessManager)
- \o CachingCapability, HostNameLookupCapability
+ \li CachingCapability, HostNameLookupCapability
\endtable
@@ -856,12 +856,12 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
the proxy:
\list
- \o the type of query
- \o the local port number to use
- \o the destination host name
- \o the destination port number
- \o the protocol name, such as "http" or "ftp"
- \o the URL being requested
+ \li the type of query
+ \li the local port number to use
+ \li the destination host name
+ \li the destination port number
+ \li the protocol name, such as "http" or "ftp"
+ \li the URL being requested
\endlist
The destination host name is the host in the connection in the
@@ -895,35 +895,35 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
\table
\header
- \o Query type
- \o Description
+ \li Query type
+ \li Description
\row
- \o TcpSocket
- \o Normal sockets requesting a connection to a remote server,
+ \li TcpSocket
+ \li Normal sockets requesting a connection to a remote server,
like QTcpSocket. The peer hostname and peer port match the
values passed to QTcpSocket::connectToHost(). The local port
is usually -1, indicating the socket has no preference in
which port should be used. The URL component is not used.
\row
- \o UdpSocket
- \o Datagram-based sockets, which can both send and
+ \li UdpSocket
+ \li Datagram-based sockets, which can both send and
receive. The local port, remote host or remote port fields
can all be used or be left unused, depending on the
characteristics of the socket. The URL component is not used.
\row
- \o TcpServer
- \o Passive server sockets that listen on a port and await
+ \li TcpServer
+ \li Passive server sockets that listen on a port and await
incoming connections from the network. Normally, only the
local port is used, but the remote address could be used in
specific circumstances, for example to indicate which remote
host a connection is expected from. The URL component is not used.
\row
- \o UrlRequest
- \o A more high-level request, such as those coming from
+ \li UrlRequest
+ \li A more high-level request, such as those coming from
QNetworkAccessManager. These requests will inevitably use an
outgoing TCP socket, but the this query type is provided to
indicate that more detailed information is present in the URL
@@ -1487,10 +1487,10 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
listed here.
\list
- \o On MacOS X, this function will ignore the Proxy Auto Configuration
+ \li On MacOS X, this function will ignore the Proxy Auto Configuration
settings, since it cannot execute the associated ECMAScript code.
- \o On Windows platforms, this function may take several seconds to
+ \li On Windows platforms, this function may take several seconds to
execute depending on the configuration of the user's system.
\endlist
*/
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 75ed17048c..d25917ee47 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -58,14 +58,14 @@
* proxy settings for:
*
* \list
- * \o FTP proxy
- * \o Web Proxy (HTTP)
- * \o Secure Web Proxy (HTTPS)
- * \o Streaming Proxy (RTSP)
- * \o SOCKS Proxy
- * \o Gopher Proxy
- * \o URL for Automatic Proxy Configuration (PAC scripts)
- * \o Bypass list (by default: *.local, 169.254/16)
+ * \li FTP proxy
+ * \li Web Proxy (HTTP)
+ * \li Secure Web Proxy (HTTPS)
+ * \li Streaming Proxy (RTSP)
+ * \li SOCKS Proxy
+ * \li Gopher Proxy
+ * \li URL for Automatic Proxy Configuration (PAC scripts)
+ * \li Bypass list (by default: *.local, 169.254/16)
* \endlist
*
* The matching configuration can be obtained by calling SCDynamicStoreCopyProxies
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 75e99fe223..2f66671530 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -56,8 +56,8 @@
you need a socket, you have two options:
\list
- \i Instantiate QTcpSocket or QUdpSocket.
- \i Create a native socket descriptor, instantiate
+ \li Instantiate QTcpSocket or QUdpSocket.
+ \li Create a native socket descriptor, instantiate
QAbstractSocket, and call setSocketDescriptor() to wrap the
native socket.
\endlist
@@ -129,15 +129,15 @@
can be used to implement blocking sockets:
\list
- \o waitForConnected() blocks until a connection has been established.
+ \li waitForConnected() blocks until a connection has been established.
- \o waitForReadyRead() blocks until new data is available for
+ \li waitForReadyRead() blocks until new data is available for
reading.
- \o waitForBytesWritten() blocks until one payload of data has been
+ \li waitForBytesWritten() blocks until one payload of data has been
written to the socket.
- \o waitForDisconnected() blocks until the connection has closed.
+ \li waitForDisconnected() blocks until the connection has closed.
\endlist
We show an example:
@@ -377,15 +377,15 @@
Possible values for the \e{TypeOfServiceOption} are:
\table
- \header \o Value \o Description
- \row \o 224 \o Network control
- \row \o 192 \o Internetwork control
- \row \o 160 \o CRITIC/ECP
- \row \o 128 \o Flash override
- \row \o 96 \o Flash
- \row \o 64 \o Immediate
- \row \o 32 \o Priority
- \row \o 0 \o Routine
+ \header \li Value \li Description
+ \row \li 224 \li Network control
+ \row \li 192 \li Internetwork control
+ \row \li 160 \li CRITIC/ECP
+ \row \li 128 \li Flash override
+ \row \li 96 \li Flash
+ \row \li 64 \li Immediate
+ \row \li 32 \li Priority
+ \row \li 0 \li Routine
\endtable
\sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
@@ -1510,7 +1510,7 @@ bool QAbstractSocket::bind(quint16 port, BindMode mode)
Returns true if the socket is valid and ready for use; otherwise
returns false.
- \bold{Note:} The socket's state must be ConnectedState before reading and
+ \b{Note:} The socket's state must be ConnectedState before reading and
writing can occur.
\sa state()
@@ -1792,7 +1792,7 @@ qintptr QAbstractSocket::socketDescriptor() const
The socket is opened in the mode specified by \a openMode, and
enters the socket state specified by \a socketState.
- \bold{Note:} It is not possible to initialize two abstract sockets
+ \b{Note:} It is not possible to initialize two abstract sockets
with the same native socket descriptor.
\sa socketDescriptor()
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index d7bbe7eb86..93a470c77f 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -427,10 +427,14 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
break;
}
- int v = -1;
+#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
+#error code assumes windows is little endian
+#endif
+ int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int
QT_SOCKOPTLEN_T len = sizeof(v);
- if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
+ if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
return v;
+ WS_ERROR_DEBUG(WSAGetLastError());
return -1;
}
@@ -563,12 +567,10 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
#if defined (IPV6_V6ONLY)
// determine if local address is dual mode
DWORD ipv6only = 0;
- int optlen = sizeof(ipv6only);
+ QT_SOCKOPTLEN_T optlen = sizeof(ipv6only);
if (localAddress == QHostAddress::AnyIPv6
&& QSysInfo::windowsVersion() >= QSysInfo::WV_6_0
&& !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
- if (optlen != sizeof(ipv6only))
- qWarning("unexpected size of IPV6_V6ONLY socket option");
if (!ipv6only) {
socketProtocol = QAbstractSocket::AnyIPProtocol;
localAddress = QHostAddress::Any;
diff --git a/src/network/socket/qtcpsocket.cpp b/src/network/socket/qtcpsocket.cpp
index 706f5721b2..dff8b5efb5 100644
--- a/src/network/socket/qtcpsocket.cpp
+++ b/src/network/socket/qtcpsocket.cpp
@@ -58,7 +58,7 @@
allows you to establish a TCP connection and transfer streams of
data. See the QAbstractSocket documentation for details.
- \bold{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode.
+ \b{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode.
\sa QTcpServer, QUdpSocket, QNetworkAccessManager,
{Fortune Server Example}, {Fortune Client Example},
diff --git a/src/network/ssl/qsslcertificateextension.cpp b/src/network/ssl/qsslcertificateextension.cpp
index eef27d7c2e..89b1a929c8 100644
--- a/src/network/ssl/qsslcertificateextension.cpp
+++ b/src/network/ssl/qsslcertificateextension.cpp
@@ -58,26 +58,26 @@
\table
\header
- \o Property
- \o Description
+ \li Property
+ \li Description
\row
- \o name
- \o The human readable name of the extension, eg. 'basicConstraints'.
+ \li name
+ \li The human readable name of the extension, eg. 'basicConstraints'.
\row
- \o criticality
- \o This is a boolean value indicating if the extension is critical
+ \li criticality
+ \li This is a boolean value indicating if the extension is critical
to correctly interpreting the certificate.
\row
- \o oid
- \o The ASN.1 object identifier that specifies which extension this
+ \li oid
+ \li The ASN.1 object identifier that specifies which extension this
is.
\row
- \o supported
- \o If this is true the structure of the extension's value will not
+ \li supported
+ \li If this is true the structure of the extension's value will not
change between Qt versions.
\row
- \o value
- \o A QVariant with a structure dependent on the type of extension.
+ \li value
+ \li A QVariant with a structure dependent on the type of extension.
\endtable
Whilst this class provides access to any type of extension, only
@@ -90,28 +90,28 @@
\table
\header
- \o Name
- \o OID
- \o Details
+ \li Name
+ \li OID
+ \li Details
\row
- \o basicConstraints
- \o 2.5.29.19
- \o Returned as a QVariantMap. The key 'ca' contains a boolean value,
+ \li basicConstraints
+ \li 2.5.29.19
+ \li Returned as a QVariantMap. The key 'ca' contains a boolean value,
the optional key 'pathLenConstraint' contains an integer.
\row
- \o authorityInfoAccess
- \o 1.3.6.1.5.5.7.1.1
- \o Returned as a QVariantMap. There is a key for each access method,
+ \li authorityInfoAccess
+ \li 1.3.6.1.5.5.7.1.1
+ \li Returned as a QVariantMap. There is a key for each access method,
with the value being a URI.
\row
- \o subjectKeyIdentifier
- \o 2.5.29.14
- \o Returned as a QVariant containing a QString. The string is the key
+ \li subjectKeyIdentifier
+ \li 2.5.29.14
+ \li Returned as a QVariant containing a QString. The string is the key
identifier.
\row
- \o authorityKeyIdentifier
- \o 2.5.29.35
- \o Returned as a QVariantMap. The optional key 'keyid' contains the key
+ \li authorityKeyIdentifier
+ \li 2.5.29.35
+ \li Returned as a QVariantMap. The optional key 'keyid' contains the key
identifier as a hex string stored in a QByteArray. The optional key
'serial' contains the authority key serial number as a qlonglong.
Currently there is no support for the general names field of this
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index dc530dae88..ec49c0f56e 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -67,11 +67,11 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
The settings that QSslConfiguration currently supports are:
\list
- \o The SSL/TLS protocol to be used
- \o The certificate to be presented to the peer during connection
+ \li The SSL/TLS protocol to be used
+ \li The certificate to be presented to the peer during connection
and its associated private key
- \o The ciphers allowed to be used for encrypting the connection
- \o The list of Certificate Authorities certificates that are
+ \li The ciphers allowed to be used for encrypting the connection
+ \li The list of Certificate Authorities certificates that are
used to validate the peer's certificate
\endlist
@@ -81,9 +81,9 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
The state that QSslConfiguration supports are:
\list
- \o The certificate the peer presented during handshake, along
+ \li The certificate the peer presented during handshake, along
with the chain leading to a CA certificate
- \o The cipher used to encrypt this session
+ \li The cipher used to encrypt this session
\endlist
The state can only be obtained once the SSL connection starts, but
@@ -541,10 +541,10 @@ bool QSslConfiguration::testSslOption(QSsl::SslOption option) const
The default SSL configuration consists of:
\list
- \o no local certificate and no private key
- \o protocol SecureProtocols (meaning either TLS 1.0 or SSL 3 will be used)
- \o the system's default CA certificate list
- \o the cipher list equal to the list of the SSL libraries'
+ \li no local certificate and no private key
+ \li protocol SecureProtocols (meaning either TLS 1.0 or SSL 3 will be used)
+ \li the system's default CA certificate list
+ \li the cipher list equal to the list of the SSL libraries'
supported SSL ciphers
\endlist
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 311ac5fe86..6338cbbe6f 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -132,12 +132,12 @@
The following features can also be customized:
\list
- \o The socket's cryptographic cipher suite can be customized before
+ \li The socket's cryptographic cipher suite can be customized before
the handshake phase with setCiphers() and setDefaultCiphers().
- \o The socket's local certificate and private key can be customized
+ \li The socket's local certificate and private key can be customized
before the handshake phase with setLocalCertificate() and
setPrivateKey().
- \o The CA certificate database can be extended and customized with
+ \li The CA certificate database can be extended and customized with
addCaCertificate(), addCaCertificates(), setCaCertificates(),
addDefaultCaCertificate(), addDefaultCaCertificates(), and
setDefaultCaCertificates().
@@ -398,7 +398,7 @@ void QSslSocket::resume()
\snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 3
- \bold{Note:} The example above shows that text can be written to
+ \b{Note:} The example above shows that text can be written to
the socket immediately after requesting the encrypted connection,
before the encrypted() signal has been emitted. In such cases, the
text is queued in the object and written to the socket \e after
@@ -468,7 +468,7 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
The socket is opened in the mode specified by \a openMode, and
enters the socket state specified by \a state.
- \bold{Note:} It is not possible to initialize two sockets with the same
+ \b{Note:} It is not possible to initialize two sockets with the same
native socket descriptor.
\sa socketDescriptor()
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 31d6064e90..eb27e865b5 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -169,17 +169,17 @@ QGLSignalProxy *QGLSignalProxy::instance()
A display format has several characteristics:
\list
- \i \link setDoubleBuffer() Double or single buffering.\endlink
- \i \link setDepth() Depth buffer.\endlink
- \i \link setRgba() RGBA or color index mode.\endlink
- \i \link setAlpha() Alpha channel.\endlink
- \i \link setAccum() Accumulation buffer.\endlink
- \i \link setStencil() Stencil buffer.\endlink
- \i \link setStereo() Stereo buffers.\endlink
- \i \link setDirectRendering() Direct rendering.\endlink
- \i \link setOverlay() Presence of an overlay.\endlink
- \i \link setPlane() Plane of an overlay.\endlink
- \i \link setSampleBuffers() Multisample buffers.\endlink
+ \li \link setDoubleBuffer() Double or single buffering.\endlink
+ \li \link setDepth() Depth buffer.\endlink
+ \li \link setRgba() RGBA or color index mode.\endlink
+ \li \link setAlpha() Alpha channel.\endlink
+ \li \link setAccum() Accumulation buffer.\endlink
+ \li \link setStencil() Stencil buffer.\endlink
+ \li \link setStereo() Stereo buffers.\endlink
+ \li \link setDirectRendering() Direct rendering.\endlink
+ \li \link setOverlay() Presence of an overlay.\endlink
+ \li \link setPlane() Plane of an overlay.\endlink
+ \li \link setSampleBuffers() Multisample buffers.\endlink
\endlist
You can also specify preferred bit depths for the color buffer,
@@ -275,17 +275,17 @@ static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz,
/*!
Constructs a QGLFormat object with the following default settings:
\list
- \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
- \i \link setDepth() Depth buffer:\endlink Enabled.
- \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
- \i \link setAlpha() Alpha channel:\endlink Disabled.
- \i \link setAccum() Accumulator buffer:\endlink Disabled.
- \i \link setStencil() Stencil buffer:\endlink Enabled.
- \i \link setStereo() Stereo:\endlink Disabled.
- \i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setOverlay() Overlay:\endlink Disabled.
- \i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
- \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
+ \li \link setDoubleBuffer() Double buffer:\endlink Enabled.
+ \li \link setDepth() Depth buffer:\endlink Enabled.
+ \li \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
+ \li \link setAlpha() Alpha channel:\endlink Disabled.
+ \li \link setAccum() Accumulator buffer:\endlink Disabled.
+ \li \link setStencil() Stencil buffer:\endlink Enabled.
+ \li \link setStereo() Stereo:\endlink Disabled.
+ \li \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \li \link setOverlay() Overlay:\endlink Disabled.
+ \li \link setPlane() Plane:\endlink 0 (i.e., normal plane).
+ \li \link setSampleBuffers() Multisample buffers:\endlink Disabled.
\endlist
*/
@@ -1339,17 +1339,17 @@ void QGLFormat::setDefaultFormat(const QGLFormat &f)
The default overlay format is:
\list
- \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
- \i \link setDepth() Depth buffer:\endlink Disabled.
- \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
- \i \link setAlpha() Alpha channel:\endlink Disabled.
- \i \link setAccum() Accumulator buffer:\endlink Disabled.
- \i \link setStencil() Stencil buffer:\endlink Disabled.
- \i \link setStereo() Stereo:\endlink Disabled.
- \i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setOverlay() Overlay:\endlink Disabled.
- \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
- \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
+ \li \link setDoubleBuffer() Double buffer:\endlink Disabled.
+ \li \link setDepth() Depth buffer:\endlink Disabled.
+ \li \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
+ \li \link setAlpha() Alpha channel:\endlink Disabled.
+ \li \link setAccum() Accumulator buffer:\endlink Disabled.
+ \li \link setStencil() Stencil buffer:\endlink Disabled.
+ \li \link setStereo() Stereo:\endlink Disabled.
+ \li \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \li \link setOverlay() Overlay:\endlink Disabled.
+ \li \link setSampleBuffers() Multisample buffers:\endlink Disabled.
+ \li \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
\endlist
\sa setDefaultFormat()
@@ -2642,10 +2642,10 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
This function supports the following use cases:
\list
- \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId,
+ \li On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId,
to the given target rectangle, \a target, in OpenGL model space. The
\a textureTarget should be a 2D texture target.
- \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a
+ \li On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a
beginNativePainting / endNativePainting block, and uses the
engine with type QPaintEngine::OpenGL2, the function will draw the given
texture, \a textureId, to the given target rectangle, \a target,
@@ -2709,10 +2709,10 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
This function supports the following use cases:
\list
- \i By default it draws the given texture, \a textureId,
+ \li By default it draws the given texture, \a textureId,
at the given \a point in OpenGL model space. The
\a textureTarget should be a 2D texture target.
- \i If a painter is active, not inside a
+ \li If a painter is active, not inside a
beginNativePainting / endNativePainting block, and uses the
engine with type QPaintEngine::OpenGL2, the function will draw the given
texture, \a textureId, at the given \a point,
@@ -3104,7 +3104,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
- \bold{Win32 only:} This virtual function chooses a pixel format
+ \b{Win32 only:} This virtual function chooses a pixel format
that matches the OpenGL \link setFormat() format\endlink.
Reimplement this function in a subclass if you need a custom
context.
@@ -3118,7 +3118,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
/*! \fn void *QGLContext::chooseVisual()
- \bold{X11 only:} This virtual function tries to find a visual that
+ \b{X11 only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
cannot be met.
@@ -3132,7 +3132,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
/*! \fn void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
\internal
- \bold{X11 only:} This virtual function chooses a visual that matches
+ \b{X11 only:} This virtual function chooses a visual that matches
the OpenGL \link format() format\endlink. Reimplement this function
in a subclass if you need a custom visual.
@@ -3220,13 +3220,13 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
reimplement in your subclass to perform the typical OpenGL tasks:
\list
- \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget
+ \li paintGL() - Renders the OpenGL scene. Gets called whenever the widget
needs to be updated.
- \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
+ \li resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
called whenever the widget has been resized (and also when it
is shown for the first time because all newly created widgets get a
resize event automatically).
- \i initializeGL() - Sets up the OpenGL rendering context, defines display
+ \li initializeGL() - Sets up the OpenGL rendering context, defines display
lists, etc. Gets called once before the first time resizeGL() or
paintGL() is called.
\endlist
@@ -3277,9 +3277,9 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
implement some or all of these virtual methods:
\list
- \i paintOverlayGL()
- \i resizeOverlayGL()
- \i initializeOverlayGL()
+ \li paintOverlayGL()
+ \li resizeOverlayGL()
+ \li initializeOverlayGL()
\endlist
These methods work in the same way as the normal paintGL() etc.
@@ -3298,9 +3298,9 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
following way:
\list
- \o Reimplement the QGLWidget::initializeGL() and QGLWidget::resizeGL() to
+ \li Reimplement the QGLWidget::initializeGL() and QGLWidget::resizeGL() to
set up the OpenGL state and provide a perspective transformation.
- \o Reimplement QGLWidget::paintGL() to paint the 3D scene, calling only
+ \li Reimplement QGLWidget::paintGL() to paint the 3D scene, calling only
OpenGL functions to draw on the widget.
\endlist
@@ -3308,10 +3308,10 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
to reimplement QGLWidget::paintEvent() and do the following:
\list
- \o Construct a QPainter object.
- \o Initialize it for use on the widget with the QPainter::begin() function.
- \o Draw primitives using QPainter's member functions.
- \o Call QPainter::end() to finish painting.
+ \li Construct a QPainter object.
+ \li Initialize it for use on the widget with the QPainter::begin() function.
+ \li Draw primitives using QPainter's member functions.
+ \li Call QPainter::end() to finish painting.
\endlist
Overpainting 2D content on top of 3D content takes a little more effort.
@@ -3323,7 +3323,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
As of Qt version 4.8, support for doing threaded GL rendering has
been improved. There are three scenarios that we currently support:
\list
- \o 1. Buffer swapping in a thread.
+ \li 1. Buffer swapping in a thread.
Swapping buffers in a double buffered context may be a
synchronous, locking call that may be a costly operation in some
@@ -3350,7 +3350,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
having the main thread wait while the GPU finishes the swap
operation. Note that this is highly implementation dependent.
- \o 2. Texture uploading in a thread.
+ \li 2. Texture uploading in a thread.
Doing texture uploads in a thread may be very useful for
applications handling large amounts of images that needs to be
@@ -3363,7 +3363,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
thread. For each texture that is bound via bindTexture(), notify
the main thread so that it can start using the texture.
- \o 3. Using QPainter to draw into a QGLWidget in a thread.
+ \li 3. Using QPainter to draw into a QGLWidget in a thread.
In Qt 4.8, it is possible to draw into a QGLWidget using a
QPainter in a separate thread. Note that this is also possible for
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 21b3abfdd8..ed362503ce 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -87,10 +87,10 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
A framebuffer object has several characteristics:
\list
- \i \link setSamples() Number of samples per pixels.\endlink
- \i \link setAttachment() Depth and/or stencil attachments.\endlink
- \i \link setTextureTarget() Texture target.\endlink
- \i \link setInternalTextureFormat() Internal texture format.\endlink
+ \li \link setSamples() Number of samples per pixels.\endlink
+ \li \link setAttachment() Depth and/or stencil attachments.\endlink
+ \li \link setTextureTarget() Texture target.\endlink
+ \li \link setInternalTextureFormat() Internal texture format.\endlink
\endlist
Note that the desired attachments or number of samples per pixels might not
@@ -674,7 +674,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
generates a 2D GL texture (using the \c{GL_TEXTURE_2D} target),
which is used as the internal rendering target.
- \bold{It is important to have a current GL context when creating a
+ \b{It is important to have a current GL context when creating a
QGLFramebufferObject, otherwise initialization will fail.}
OpenGL framebuffer objects and pbuffers (see
@@ -683,22 +683,22 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
using framebuffer objects instead of pbuffers:
\list 1
- \o A framebuffer object does not require a separate rendering
+ \li A framebuffer object does not require a separate rendering
context, so no context switching will occur when switching
rendering targets. There is an overhead involved in switching
targets, but in general it is cheaper than a context switch to a
pbuffer.
- \o Rendering to dynamic textures (i.e. render-to-texture
+ \li Rendering to dynamic textures (i.e. render-to-texture
functionality) works on all platforms. No need to do explicit copy
calls from a render buffer into a texture, as was necessary on
systems that did not support the \c{render_texture} extension.
- \o It is possible to attach several rendering buffers (or texture
+ \li It is possible to attach several rendering buffers (or texture
objects) to the same framebuffer object, and render to all of them
without doing a context switch.
- \o The OpenGL framebuffer extension is a pure GL extension with no
+ \li The OpenGL framebuffer extension is a pure GL extension with no
system dependant WGL, CGL, or GLX parts. This makes using
framebuffer objects more portable.
\endlist
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index ab5a738ba7..bccac7e9a0 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -53,16 +53,16 @@
There are three approaches to using this class:
\list 1
- \o \bold{We can draw into the pbuffer and convert it to a QImage
+ \li \b{We can draw into the pbuffer and convert it to a QImage
using toImage().} This is normally much faster than calling
QGLWidget::renderPixmap().
- \o \bold{We can draw into the pbuffer and copy the contents into
+ \li \b{We can draw into the pbuffer and copy the contents into
an OpenGL texture using updateDynamicTexture().} This allows
us to create dynamic textures and works on all systems
with pbuffer support.
- \o \bold{On systems that support it, we can bind the pbuffer to
+ \li \b{On systems that support it, we can bind the pbuffer to
an OpenGL texture.} The texture is then updated automatically
when the pbuffer contents change, eliminating the need for
additional copy operations. This is supported only on Windows
diff --git a/src/platformsupport/dnd/dnd.pri b/src/platformsupport/dnd/dnd.pri
index e100dd10cb..47feb81ef2 100644
--- a/src/platformsupport/dnd/dnd.pri
+++ b/src/platformsupport/dnd/dnd.pri
@@ -1,4 +1,6 @@
HEADERS += \
- $$PWD/qsimpledrag_p.h
+ $$PWD/qsimpledrag_p.h \
+ $$PWD/qshapedpixmapdndwindow_p.h
SOURCES += \
- $$PWD/qsimpledrag.cpp
+ $$PWD/qsimpledrag.cpp \
+ $$PWD/qshapedpixmapdndwindow.cpp
diff --git a/src/gui/image/qvolatileimagedata.cpp b/src/platformsupport/dnd/qshapedpixmapdndwindow.cpp
index 3fcf24e187..4eed1e7d85 100644
--- a/src/gui/image/qvolatileimagedata.cpp
+++ b/src/platformsupport/dnd/qshapedpixmapdndwindow.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,76 +39,62 @@
**
****************************************************************************/
-#include "qvolatileimagedata_p.h"
-#include <QtGui/qpaintengine.h>
+#include "qshapedpixmapdndwindow_p.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QCursor>
QT_BEGIN_NAMESPACE
-QVolatileImageData::QVolatileImageData()
- : pengine(0)
+QShapedPixmapWindow::QShapedPixmapWindow()
+ : QWindow(),
+ m_backingStore(0)
{
+ setSurfaceType(RasterSurface);
+ setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint |
+ Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput);
+ create();
+ m_backingStore = new QBackingStore(this);
}
-QVolatileImageData::QVolatileImageData(int w, int h, QImage::Format format)
- : pengine(0)
+void QShapedPixmapWindow::render()
{
- image = QImage(w, h, format);
-}
+ QRect rect(QPoint(), geometry().size());
-QVolatileImageData::QVolatileImageData(const QImage &sourceImage)
- : pengine(0)
-{
- image = sourceImage;
-}
-
-QVolatileImageData::QVolatileImageData(void *, void *)
- : pengine(0)
-{
- // Not supported.
-}
+ m_backingStore->beginPaint(rect);
-QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
- : QSharedData()
-{
- image = other.image;
- // The detach is not mandatory here but we do it nonetheless in order to
- // keep the behavior consistent with other platforms.
- image.detach();
- pengine = 0;
-}
+ QPaintDevice *device = m_backingStore->paintDevice();
-QVolatileImageData::~QVolatileImageData()
-{
- delete pengine;
-}
+ {
+ QPainter p(device);
+ p.drawPixmap(0, 0, m_pixmap);
+ }
-void QVolatileImageData::beginDataAccess() const
-{
- // nothing to do here
+ m_backingStore->endPaint();
+ m_backingStore->flush(rect);
}
-void QVolatileImageData::endDataAccess(bool readOnly) const
+void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
- Q_UNUSED(readOnly);
- // nothing to do here
+ m_pixmap = pixmap;
}
-bool QVolatileImageData::ensureFormat(QImage::Format format)
+void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
{
- if (image.format() != format) {
- image = image.convertToFormat(format);
- }
- return true;
+ m_hotSpot = hotspot;
}
-void *QVolatileImageData::duplicateNativeImage() const
+void QShapedPixmapWindow::updateGeometry()
{
- return 0;
+ QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size());
+ if (m_backingStore->size() != m_pixmap.size())
+ m_backingStore->resize(m_pixmap.size());
+ setGeometry(rect);
}
-void QVolatileImageData::ensureImage()
+void QShapedPixmapWindow::exposeEvent(QExposeEvent *)
{
- // nothing to do here
+ render();
}
QT_END_NAMESPACE
diff --git a/config.tests/unix/endian/endiantest.cpp b/src/platformsupport/dnd/qshapedpixmapdndwindow_p.h
index e08a11b944..36ca6040dd 100644
--- a/config.tests/unix/endian/endiantest.cpp
+++ b/src/platformsupport/dnd/qshapedpixmapdndwindow_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,18 +39,40 @@
**
****************************************************************************/
-// "MostSignificantByteFirst"
-short msb_bigendian[] = { 0x0000, 0x4d6f, 0x7374, 0x5369, 0x676e, 0x6966, 0x6963, 0x616e, 0x7442, 0x7974, 0x6546, 0x6972, 0x7374, 0x0000 };
+#ifndef QSHAPEDPIXMAPDNDWINDOW_H
+#define QSHAPEDPIXMAPDNDWINDOW_H
-// "LeastSignificantByteFirst"
-short lsb_littleendian[] = { 0x0000, 0x654c, 0x7361, 0x5374, 0x6769, 0x696e, 0x6966, 0x6163, 0x746e, 0x7942, 0x6574, 0x6946, 0x7372, 0x0074, 0x0000 };
+#include <QtGui/QWindow>
+#include <QtGui/QPixmap>
+#include <QtGui/QBackingStore>
-int main(int, char **)
+QT_BEGIN_NAMESPACE
+
+QT_BEGIN_HEADER
+
+class QShapedPixmapWindow : public QWindow
{
- // make sure the linker doesn't throw away the arrays
- void (*msb_bigendian_string)() = (void (*)())msb_bigendian;
- void (*lsb_littleendian_string)() = (void (*)())lsb_littleendian;
- (void)msb_bigendian_string();
- (void)lsb_littleendian_string();
- return msb_bigendian[1] == lsb_littleendian[1];
-}
+public:
+ QShapedPixmapWindow();
+
+ void render();
+
+ void setPixmap(const QPixmap &pixmap);
+ void setHotspot(const QPoint &hotspot);
+
+ void updateGeometry();
+
+protected:
+ void exposeEvent(QExposeEvent *);
+
+private:
+ QBackingStore *m_backingStore;
+ QPixmap m_pixmap;
+ QPoint m_hotSpot;
+};
+
+QT_END_HEADER
+
+QT_END_NAMESPACE
+
+#endif // QSHAPEDPIXMAPDNDWINDOW_H
diff --git a/src/platformsupport/dnd/qsimpledrag.cpp b/src/platformsupport/dnd/qsimpledrag.cpp
index d0d08c2445..d3cecd4e44 100644
--- a/src/platformsupport/dnd/qsimpledrag.cpp
+++ b/src/platformsupport/dnd/qsimpledrag.cpp
@@ -56,147 +56,283 @@
#include "qimagereader.h"
#include "qimagewriter.h"
+#include <QtCore/QEventLoop>
+#include <QtCore/QDebug>
+
#include <private/qguiapplication_p.h>
#include <private/qdnd_p.h>
+#include <QtPlatformSupport/private/qshapedpixmapdndwindow_p.h>
+
QT_BEGIN_NAMESPACE
-class QDropData : public QInternalMimeData
-{
-public:
- QDropData();
- ~QDropData();
+/*!
+ \class QBasicDrag
+ \brief QBasicDrag is a base class for implementing platform drag and drop.
+ \since 5.0
+ \internal
+ \ingroup qpa
-protected:
- bool hasFormat_sys(const QString &mimeType) const;
- QStringList formats_sys() const;
- QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
-};
+ QBasicDrag implements QPlatformDrag::drag() by running a local event loop in which
+ it tracks mouse movements and moves the drag icon (QShapedPixmapWindow) accordingly.
+ It provides new virtuals allowing for querying whether the receiving window
+ (within the Qt application or outside) accepts the drag and sets the state accordingly.
+*/
-QSimpleDrag::QSimpleDrag()
+QBasicDrag::QBasicDrag() :
+ m_restoreCursor(false), m_eventLoop(0),
+ m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
+ m_drag(0), m_drag_icon_window(0), m_cursor_drop_action(Qt::IgnoreAction)
{
- m_dropData = new QDropData();
- currentWindow = 0;
}
-QSimpleDrag::~QSimpleDrag()
+QBasicDrag::~QBasicDrag()
{
- delete m_dropData;
+ delete m_drag_icon_window;
}
-QMimeData *QSimpleDrag::platformDropData()
+void QBasicDrag::enableEventFilter()
{
- return m_dropData;
+ qApp->installEventFilter(this);
}
-void QSimpleDrag::cancel()
+void QBasicDrag::disableEventFilter()
{
- QDragManager *m = QDragManager::self();
-// qDebug("QDragManager::cancel");
- if (m->object->target()) {
- QDragLeaveEvent dle;
- QCoreApplication::sendEvent(m->object->target(), &dle);
- }
-
+ qApp->removeEventFilter(this);
}
-void QSimpleDrag::move(const QMouseEvent *me)
+bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
{
- QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
- QPoint pos;
- if (window)
- pos = me->globalPos() - window->geometry().topLeft();
+ if (!m_drag) {
+ if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
+ disableEventFilter();
+ exitDndEventLoop();
+ return true; // block the key release
+ }
+ return false;
+ }
- QDragManager *m = QDragManager::self();
+ if (!qobject_cast<QWindow *>(o))
+ return false;
- if (me->buttons()) {
- Qt::DropAction prevAction = m->global_accepted_action;
+ switch (e->type()) {
+ case QEvent::ShortcutOverride:
+ // prevent accelerators from firing while dragging
+ e->accept();
+ return true;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
+ cancel();
+ resetDndState(true);
+ disableEventFilter();
+ exitDndEventLoop();
- if (currentWindow != window) {
- if (currentWindow) {
- QDragLeaveEvent dle;
- QCoreApplication::sendEvent(currentWindow, &dle);
- m->willDrop = false;
- m->global_accepted_action = Qt::IgnoreAction;
- }
- currentWindow = window;
- if (currentWindow) {
- QDragEnterEvent dee(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
- QCoreApplication::sendEvent(currentWindow, &dee);
- m->willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
- m->global_accepted_action = m->willDrop ? dee.dropAction() : Qt::IgnoreAction;
- }
- m->updateCursor();
- } else if (window) {
- Q_ASSERT(currentWindow);
- QDragMoveEvent dme(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
- if (m->global_accepted_action != Qt::IgnoreAction) {
- dme.setDropAction(m->global_accepted_action);
- dme.accept();
}
- QCoreApplication::sendEvent(currentWindow, &dme);
- m->willDrop = dme.isAccepted();
- m->global_accepted_action = m->willDrop ? dme.dropAction() : Qt::IgnoreAction;
- m->updatePixmap();
- m->updateCursor();
+ return true; // Eat all key events
}
- if (m->global_accepted_action != prevAction)
- m->emitActionChanged(m->global_accepted_action);
+
+ case QEvent::MouseMove:
+ move(static_cast<QMouseEvent *>(e));
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonRelease:
+ disableEventFilter();
+
+ if (canDrop()) {
+ drop(static_cast<QMouseEvent *>(e));
+ resetDndState(false);
+ } else {
+ cancel();
+ resetDndState(true);
+ }
+ exitDndEventLoop();
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ return true;
+ default:
+ break;
}
+ return false;
}
-void QSimpleDrag::drop(const QMouseEvent *me)
+Qt::DropAction QBasicDrag::drag(QDrag *o)
{
- QDragManager *m = QDragManager::self();
+ m_drag = o;
+ m_executed_drop_action = Qt::IgnoreAction;
+ m_can_drop = false;
+ m_restoreCursor = true;
+#ifndef QT_NO_CURSOR
+ qApp->setOverrideCursor(Qt::DragCopyCursor);
+ updateCursor(m_executed_drop_action);
+#endif
+ startDrag();
+ m_eventLoop = new QEventLoop;
+ m_eventLoop->exec();
+ delete m_eventLoop;
+ m_eventLoop = 0;
+ m_drag = 0;
+ endDrag();
+ return m_executed_drop_action;
+}
- QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
+void QBasicDrag::resetDndState(bool /* deleteSource */)
+{
+ if (m_restoreCursor) {
+#ifndef QT_NO_CURSOR
+ QGuiApplication::restoreOverrideCursor();
+#endif
+ m_restoreCursor = false;
+ }
+}
+
+void QBasicDrag::startDrag()
+{
+ if (!m_drag_icon_window)
+ m_drag_icon_window = new QShapedPixmapWindow();
+
+ m_drag_icon_window->setPixmap(m_drag->pixmap());
+ m_drag_icon_window->setHotspot(m_drag->hotSpot());
+ m_drag_icon_window->updateGeometry();
+ m_drag_icon_window->setVisible(true);
+
+ enableEventFilter();
+}
+
+void QBasicDrag::endDrag()
+{
+}
+
+void QBasicDrag::cancel()
+{
+ disableEventFilter();
+ m_drag_icon_window->setVisible(false);
+}
+
+void QBasicDrag::move(const QMouseEvent *)
+{
+ if (m_drag)
+ m_drag_icon_window->updateGeometry();
+}
- if (window) {
- QPoint pos = me->globalPos() - window->geometry().topLeft();
+void QBasicDrag::drop(const QMouseEvent *)
+{
+ disableEventFilter();
+ m_drag_icon_window->setVisible(false);
+}
+
+void QBasicDrag::exitDndEventLoop()
+{
+ if (m_eventLoop && m_eventLoop->isRunning())
+ m_eventLoop->exit();
+}
- QDropEvent de(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
- QCoreApplication::sendEvent(window, &de);
- if (de.isAccepted())
- m->global_accepted_action = de.dropAction();
- else
- m->global_accepted_action = Qt::IgnoreAction;
+void QBasicDrag::updateCursor(Qt::DropAction action)
+{
+ Qt::CursorShape cursorShape = Qt::ForbiddenCursor;
+ if (canDrop()) {
+ switch (action) {
+ case Qt::CopyAction:
+ cursorShape = Qt::DragCopyCursor;
+ break;
+ case Qt::LinkAction:
+ cursorShape = Qt::DragLinkCursor;
+ break;
+ default:
+ cursorShape = Qt::DragMoveCursor;
+ break;
+ }
}
- currentWindow = 0;
+
+ QCursor *cursor = qApp->overrideCursor();
+ if (cursor && cursorShape != cursor->shape()) {
+ qApp->changeOverrideCursor(QCursor(cursorShape));
+ }
+ updateAction(action);
}
+/*!
+ \class QSimpleDrag
+ \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself.
+ \since 5.0
+ \internal
+ \ingroup qpa
+ The class checks whether the receiving window is a window of the Qt application
+ and sets the state accordingly. It does not take windows of other applications
+ into account.
+*/
-QDropData::QDropData()
- : QInternalMimeData()
+QSimpleDrag::QSimpleDrag() : m_current_window(0)
{
}
-QDropData::~QDropData()
+QMimeData *QSimpleDrag::platformDropData()
{
+ if (drag())
+ return drag()->mimeData();
+ return 0;
}
-QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
+void QSimpleDrag::startDrag()
{
- QDrag *object = QDragManager::self()->object;
- if (!object)
- return QVariant();
- QByteArray data = object->mimeData()->data(mimetype);
- if (type == QVariant::String)
- return QString::fromUtf8(data);
- return data;
+ QBasicDrag::startDrag();
+ m_current_window = QGuiApplication::topLevelAt(QCursor::pos());
+ if (m_current_window) {
+ QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions());
+ setCanDrop(response.isAccepted());
+ updateCursor(response.acceptedAction());
+ } else {
+ setCanDrop(false);
+ updateCursor(Qt::IgnoreAction);
+ }
+ setExecutedDropAction(Qt::IgnoreAction);
}
-bool QDropData::hasFormat_sys(const QString &format) const
+void QSimpleDrag::cancel()
{
- return formats().contains(format);
+ QBasicDrag::cancel();
+ if (drag())
+ QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction);
+ m_current_window = 0;
}
-QStringList QDropData::formats_sys() const
+void QSimpleDrag::move(const QMouseEvent *me)
{
- QDrag *object = QDragManager::self()->object;
- if (object)
- return object->mimeData()->formats();
- return QStringList();
+ QBasicDrag::move(me);
+ QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
+ if (!window)
+ return;
+
+ const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPlatformDragQtResponse qt_response =
+ QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
+
+ updateCursor(qt_response.acceptedAction());
+ setCanDrop(qt_response.isAccepted());
+}
+
+void QSimpleDrag::drop(const QMouseEvent *me)
+{
+ QBasicDrag::drop(me);
+ QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
+ if (!window)
+ return;
+
+ const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPlatformDropQtResponse response =
+ QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
+ if (response.isAccepted()) {
+ setExecutedDropAction(response.acceptedAction());
+ } else {
+ setExecutedDropAction(Qt::IgnoreAction);
+ }
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/dnd/qsimpledrag_p.h b/src/platformsupport/dnd/qsimpledrag_p.h
index 536ae241ff..7270684082 100644
--- a/src/platformsupport/dnd/qsimpledrag_p.h
+++ b/src/platformsupport/dnd/qsimpledrag_p.h
@@ -44,32 +44,80 @@
#include <qplatformdrag_qpa.h>
+#include <QtCore/QObject>
+
QT_BEGIN_NAMESPACE
+QT_BEGIN_HEADER
+
class QMouseEvent;
class QWindow;
-
+class QEventLoop;
class QDropData;
+class QShapedPixmapWindow;
-class QSimpleDrag : public QPlatformDrag
+class QBasicDrag : public QPlatformDrag, public QObject
{
public:
- QSimpleDrag();
- ~QSimpleDrag();
+ virtual ~QBasicDrag();
- virtual QMimeData *platformDropData();
+ virtual Qt::DropAction drag(QDrag *drag);
+
+ virtual bool eventFilter(QObject *o, QEvent *e);
-// virtual Qt::DropAction drag(QDrag *);
+protected:
+ QBasicDrag();
+ virtual void startDrag();
virtual void cancel();
virtual void move(const QMouseEvent *me);
virtual void drop(const QMouseEvent *me);
+ virtual void endDrag();
+
+ QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; }
+ void updateCursor(Qt::DropAction action);
+
+ bool canDrop() const { return m_can_drop; }
+ void setCanDrop(bool c) { m_can_drop = c; }
+
+ Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
+ void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
+
+ QDrag *drag() const { return m_drag; }
+
private:
- QDropData *m_dropData;
+ void enableEventFilter();
+ void disableEventFilter();
+ void resetDndState(bool deleteSource);
+ void exitDndEventLoop();
+
+ bool m_restoreCursor;
+ QEventLoop *m_eventLoop;
+ Qt::DropAction m_executed_drop_action;
+ bool m_can_drop;
+ QDrag *m_drag;
+ QShapedPixmapWindow *m_drag_icon_window;
+ Qt::DropAction m_cursor_drop_action;
+};
+
+class QSimpleDrag : public QBasicDrag
+{
+public:
+ QSimpleDrag();
+ virtual QMimeData *platformDropData();
- QWindow *currentWindow;
+protected:
+ virtual void startDrag();
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+
+private:
+ QWindow *m_current_window;
};
+QT_END_HEADER
+
QT_END_NAMESPACE
#endif
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
index 0f6e2ae8d5..3d3253be64 100644
--- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
@@ -86,7 +86,7 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
if (chosenVisualInfo) {
// Skip size checks if implementation supports non-matching visual
- // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
+ // and config (http://bugreports.qt-project.org/browse/QTBUG-9444).
if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
XFree(chosenVisualInfo);
return visualId;
diff --git a/src/platformsupport/glxconvenience/glxconvenience.pri b/src/platformsupport/glxconvenience/glxconvenience.pri
index 3632f45b54..6915f8db4e 100644
--- a/src/platformsupport/glxconvenience/glxconvenience.pri
+++ b/src/platformsupport/glxconvenience/glxconvenience.pri
@@ -1,6 +1,5 @@
contains(QT_CONFIG,xlib):contains(QT_CONFIG,xrender) {
contains(QT_CONFIG,opengl):!contains(QT_CONFIG,opengles2) {
- LIBS += $$QMAKE_LIBS_X11 -lXrender
HEADERS += $$PWD/qglxconvenience_p.h
SOURCES += $$PWD/qglxconvenience.cpp
}
diff --git a/src/platformsupport/udev/udev.pri b/src/platformsupport/udev/udev.pri
index 48ad9d36af..21c71d5f5b 100644
--- a/src/platformsupport/udev/udev.pri
+++ b/src/platformsupport/udev/udev.pri
@@ -1,5 +1,4 @@
contains(QT_CONFIG, libudev) {
HEADERS += $$PWD/qudevhelper_p.h $$PWD/qudevicehelper_p.h
SOURCES += $$PWD/qudevhelper.cpp $$PWD/qudevicehelper.cpp
- LIBS += -ludev
}
diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmouse.cpp
index 0b72123c02..be779c68a5 100644
--- a/src/plugins/generic/evdevmouse/qevdevmouse.cpp
+++ b/src/plugins/generic/evdevmouse/qevdevmouse.cpp
@@ -176,12 +176,27 @@ void QEvdevMouseHandler::readMouseData()
sendMouseEvent();
pendingMouseEvent = false;
- } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_MIDDLE) {
+ } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_JOYSTICK) {
Qt::MouseButton button = Qt::NoButton;
+ // BTN_LEFT == 0x110 in kernel's input.h
+ // The range of possible mouse buttons ends just before BTN_JOYSTICK, value 0x120.
switch (data->code) {
- case BTN_LEFT: button = Qt::LeftButton; break;
- case BTN_MIDDLE: button = Qt::MidButton; break;
- case BTN_RIGHT: button = Qt::RightButton; break;
+ case 0x110: button = Qt::LeftButton; break; // BTN_LEFT
+ case 0x111: button = Qt::RightButton; break;
+ case 0x112: button = Qt::MiddleButton; break;
+ case 0x113: button = Qt::ExtraButton1; break; // AKA Qt::BackButton
+ case 0x114: button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton
+ case 0x115: button = Qt::ExtraButton3; break; // AKA Qt::TaskButton
+ case 0x116: button = Qt::ExtraButton4; break;
+ case 0x117: button = Qt::ExtraButton5; break;
+ case 0x118: button = Qt::ExtraButton6; break;
+ case 0x119: button = Qt::ExtraButton7; break;
+ case 0x11a: button = Qt::ExtraButton8; break;
+ case 0x11b: button = Qt::ExtraButton9; break;
+ case 0x11c: button = Qt::ExtraButton10; break;
+ case 0x11d: button = Qt::ExtraButton11; break;
+ case 0x11e: button = Qt::ExtraButton12; break;
+ case 0x11f: button = Qt::ExtraButton13; break;
}
if (data->value)
m_buttons |= button;
diff --git a/src/plugins/generic/evdevtouch/README b/src/plugins/generic/evdevtouch/README
index 4764ef8f70..119f2a2c9e 100644
--- a/src/plugins/generic/evdevtouch/README
+++ b/src/plugins/generic/evdevtouch/README
@@ -1,8 +1,14 @@
-Generic plug-in for evdev touch events. (protocol type A)
+Generic plug-in for evdev touch (ABS_MT) events.
+Supports protocol type A & B.
+Type B is supported both directly and via libmtdev.
-Tested with the following drivers: bcm5974, hid_magicmouse.
+The protocol type will be detected automatically.
+To enable libmtdev support uncomment the USE_MTDEV define in
+evdevtouch.pro.
-To use it, pass -plugin EvdevTouch on the command line.
+Tested with the following kernel drivers: bcm5974, hid_magicmouse.
+
+To use this "driver", pass -plugin EvdevTouch on the command line.
If automatic detection does not work, use -plugin
EvdevTouch:/dev/input/eventN to explicitly set the device file
diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro
index 284f1d1221..f9fb4a61d8 100644
--- a/src/plugins/generic/evdevtouch/evdevtouch.pro
+++ b/src/plugins/generic/evdevtouch/evdevtouch.pro
@@ -15,3 +15,7 @@ QT += core-private platformsupport-private
OTHER_FILES += \
evdevtouch.json
+
+# DEFINES += USE_MTDEV
+
+contains(DEFINES, USE_MTDEV): LIBS += -lmtdev
diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.cpp b/src/plugins/generic/evdevtouch/qevdevtouch.cpp
index d508c4a12a..73f253ae96 100644
--- a/src/plugins/generic/evdevtouch/qevdevtouch.cpp
+++ b/src/plugins/generic/evdevtouch/qevdevtouch.cpp
@@ -49,8 +49,18 @@
#include <QtPlatformSupport/private/qudevhelper_p.h>
#include <linux/input.h>
+#ifdef USE_MTDEV
+extern "C" {
+#include <mtdev.h>
+}
+#endif
+
QT_BEGIN_NAMESPACE
+#ifndef ABS_MT_SLOT
+#define ABS_MT_SLOT 0x2f
+#endif
+
class QTouchScreenData
{
public:
@@ -75,8 +85,10 @@ public:
x(0), y(0), maj(1), pressure(0),
state(Qt::TouchPointPressed), flags(0) { }
};
- QHash<int, Contact> m_contacts, m_lastContacts;
+ QHash<int, Contact> m_contacts; // The key is a tracking id for type A, slot number for type B.
+ QHash<int, Contact> m_lastContacts;
Contact m_currentData;
+ int m_currentSlot;
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
void reportPoints();
@@ -91,11 +103,13 @@ public:
QString hw_name;
bool m_forceToActiveWindow;
QTouchDevice *m_device;
+ bool m_typeB;
};
QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args)
: q(q_ptr),
m_lastEventType(-1),
+ m_currentSlot(0),
hw_range_x_min(0), hw_range_x_max(0),
hw_range_y_min(0), hw_range_y_max(0),
hw_pressure_min(0), hw_pressure_max(0)
@@ -115,8 +129,19 @@ void QTouchScreenData::registerDevice()
QWindowSystemInterface::registerTouchDevice(m_device);
}
+#define LONG_BITS (sizeof(long) << 3)
+#define NUM_LONGS(bits) (((bits) + LONG_BITS - 1) / LONG_BITS)
+
+static inline bool testBit(long bit, const long *array)
+{
+ return array[bit / LONG_BITS] & (1 << (bit & (LONG_BITS - 1)));
+}
+
QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
: m_notify(0), m_fd(-1), d(0)
+#ifdef USE_MTDEV
+ , m_mtdev(0)
+#endif
{
setObjectName(QLatin1String("Evdev Touch Handler"));
@@ -141,6 +166,16 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
return;
}
+#ifdef USE_MTDEV
+ m_mtdev = static_cast<mtdev *>(calloc(1, sizeof(mtdev)));
+ int mtdeverr = mtdev_open(m_mtdev, m_fd);
+ if (mtdeverr) {
+ qWarning("mtdev_open failed: %d", mtdeverr);
+ QT_CLOSE(m_fd);
+ return;
+ }
+#endif
+
d = new QTouchScreenData(this, args);
input_absinfo absInfo;
@@ -168,11 +203,30 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
qDebug("device name: %s", name);
}
+#ifdef USE_MTDEV
+ const char *mtdevStr = "(mtdev)";
+ d->m_typeB = true;
+#else
+ const char *mtdevStr = "";
+ d->m_typeB = false;
+ long absbits[NUM_LONGS(ABS_CNT)];
+ if (ioctl(m_fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits) >= 0)
+ d->m_typeB = testBit(ABS_MT_SLOT, absbits);
+#endif
+ qDebug("Protocol type %c %s", d->m_typeB ? 'B' : 'A', mtdevStr);
+
d->registerDevice();
}
QTouchScreenHandler::~QTouchScreenHandler()
{
+#ifdef USE_MTDEV
+ if (m_mtdev) {
+ mtdev_close(m_mtdev);
+ free(m_mtdev);
+ }
+#endif
+
if (m_fd >= 0)
QT_CLOSE(m_fd);
@@ -184,8 +238,13 @@ void QTouchScreenHandler::readData()
::input_event buffer[32];
int n = 0;
for (; ;) {
+#ifdef USE_MTDEV
+ n = mtdev_get(m_mtdev, m_fd, buffer, sizeof(buffer) / sizeof(::input_event));
+ if (n > 0)
+ n *= sizeof(::input_event);
+#else
n = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n);
-
+#endif
if (!n) {
qWarning("Got EOF from input device");
return;
@@ -215,16 +274,32 @@ void QTouchScreenData::processInputEvent(input_event *data)
if (data->code == ABS_MT_POSITION_X) {
m_currentData.x = qBound(hw_range_x_min, data->value, hw_range_x_max);
+ if (m_typeB)
+ m_contacts[m_currentSlot].x = m_currentData.x;
} else if (data->code == ABS_MT_POSITION_Y) {
m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max);
+ if (m_typeB)
+ m_contacts[m_currentSlot].y = m_currentData.y;
} else if (data->code == ABS_MT_TRACKING_ID) {
m_currentData.trackingId = data->value;
+ if (m_typeB) {
+ if (m_currentData.trackingId == -1)
+ m_contacts[m_currentSlot].state = Qt::TouchPointReleased;
+ else
+ m_contacts[m_currentSlot].trackingId = m_currentData.trackingId;
+ }
} else if (data->code == ABS_MT_TOUCH_MAJOR) {
m_currentData.maj = data->value;
if (data->value == 0)
m_currentData.state = Qt::TouchPointReleased;
+ if (m_typeB)
+ m_contacts[m_currentSlot].maj = m_currentData.maj;
} else if (data->code == ABS_PRESSURE) {
m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max);
+ if (m_typeB)
+ m_contacts[m_currentSlot].pressure = m_currentData.pressure;
+ } else if (data->code == ABS_MT_SLOT) {
+ m_currentSlot = data->value;
}
} else if (data->type == EV_SYN && data->code == SYN_MT_REPORT && m_lastEventType != EV_SYN) {
@@ -254,8 +329,9 @@ void QTouchScreenData::processInputEvent(input_event *data)
tp.id = contact.trackingId;
tp.flags = contact.flags;
- if (m_lastContacts.contains(contact.trackingId)) {
- const Contact &prev(m_lastContacts.value(contact.trackingId));
+ int key = m_typeB ? it.key() : contact.trackingId;
+ if (m_lastContacts.contains(key)) {
+ const Contact &prev(m_lastContacts.value(key));
if (contact.state == Qt::TouchPointReleased) {
// Copy over the previous values for released points, just in case.
contact.x = prev.x;
@@ -269,7 +345,7 @@ void QTouchScreenData::processInputEvent(input_event *data)
// Avoid reporting a contact in released state more than once.
if (contact.state == Qt::TouchPointReleased
- && !m_lastContacts.contains(contact.trackingId)) {
+ && !m_lastContacts.contains(key)) {
it.remove();
continue;
}
@@ -293,7 +369,8 @@ void QTouchScreenData::processInputEvent(input_event *data)
}
m_lastContacts = m_contacts;
- m_contacts.clear();
+ if (!m_typeB)
+ m_contacts.clear();
if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary)
reportPoints();
diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.h b/src/plugins/generic/evdevtouch/qevdevtouch.h
index 343f638526..28a3b215fb 100644
--- a/src/plugins/generic/evdevtouch/qevdevtouch.h
+++ b/src/plugins/generic/evdevtouch/qevdevtouch.h
@@ -54,6 +54,9 @@ QT_BEGIN_NAMESPACE
class QSocketNotifier;
class QTouchScreenData;
+#ifdef USE_MTDEV
+struct mtdev;
+#endif
class QTouchScreenHandler : public QObject
{
@@ -67,11 +70,12 @@ private slots:
void readData();
private:
- void pathFromUdev(QString *path);
-
QSocketNotifier *m_notify;
int m_fd;
QTouchScreenData *d;
+#ifdef USE_MTDEV
+ mtdev *m_mtdev;
+#endif
};
class QTouchScreenHandlerThread : public QThread
diff --git a/src/plugins/platforms/blackberry/qbbclipboard.cpp b/src/plugins/platforms/blackberry/qbbclipboard.cpp
index fce016d5ee..293a0c771b 100644
--- a/src/plugins/platforms/blackberry/qbbclipboard.cpp
+++ b/src/plugins/platforms/blackberry/qbbclipboard.cpp
@@ -46,6 +46,7 @@
#include <QtGui/QColor>
#include <QtCore/QDebug>
+#include <QtCore/QMimeData>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
@@ -53,11 +54,131 @@
#include <errno.h>
QT_BEGIN_NAMESPACE
-static const char *typeList[] = {"text/html", "text/plain", "application/x-color"};
+
+// null terminated array
+static const char *typeList[] = {"text/html", "text/plain", "image/png", "image/jpeg", "application/x-color", 0};
+
+static QByteArray readClipboardBuff(const char *type)
+{
+ char *pbuffer;
+ if (is_clipboard_format_present(type) == 0) {
+ int size = get_clipboard_data(type, &pbuffer);
+ if (size != -1 && pbuffer) {
+ const QByteArray result = QByteArray(pbuffer, size);
+ free(pbuffer);
+ return result;
+ }
+ }
+
+ return QByteArray();
+}
+
+class QBBClipboard::MimeData : public QMimeData
+{
+ Q_OBJECT
+public:
+ MimeData(QBBClipboard *clipboard)
+ : QMimeData(),
+ m_clipboard(clipboard),
+ m_userMimeData(0)
+ {
+ Q_ASSERT(clipboard);
+
+ for (int i = 0; typeList[i] != 0; ++i) {
+ m_formatsToCheck << QString::fromUtf8(typeList[i]);
+ }
+ }
+
+ ~MimeData()
+ {
+ delete m_userMimeData;
+ }
+
+ void addFormatToCheck(const QString &format) {
+ m_formatsToCheck << format;
+
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "formats=" << m_formatsToCheck;
+#endif
+ }
+
+ bool hasFormat(const QString &mimetype) const
+ {
+ const bool result = is_clipboard_format_present(mimetype.toUtf8().constData()) == 0;
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "result=" << result;
+#endif
+ return result;
+ }
+
+ QStringList formats() const
+ {
+ QStringList result;
+
+ Q_FOREACH (const QString &format, m_formatsToCheck) {
+ if (is_clipboard_format_present(format.toUtf8().constData()) == 0)
+ result << format;
+ }
+
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "result=" << result;
+#endif
+ return result;
+ }
+
+ void setUserMimeData(QMimeData *userMimeData)
+ {
+ delete m_userMimeData;
+ m_userMimeData = userMimeData;
+
+ // system clipboard API doesn't allow detection of changes by other applications
+ // simulate an owner change through delayed invocation
+ // basically transfer ownership of data to the system clipboard once event processing resumes
+ if (m_userMimeData)
+ QMetaObject::invokeMethod(this, "releaseOwnership", Qt::QueuedConnection);
+ }
+
+ QMimeData *userMimeData()
+ {
+ return m_userMimeData;
+ }
+
+protected:
+ QVariant retrieveData(const QString &mimetype, QVariant::Type preferredType) const
+ {
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "preferredType=" << preferredType;
+#endif
+ if (is_clipboard_format_present(mimetype.toUtf8().constData()) != 0)
+ return QMimeData::retrieveData(mimetype, preferredType);
+
+ const QByteArray data = readClipboardBuff(mimetype.toUtf8().constData());
+ return qVariantFromValue(data);
+ }
+
+private Q_SLOTS:
+ void releaseOwnership()
+ {
+ if (m_userMimeData) {
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats();
+#endif
+ delete m_userMimeData;
+ m_userMimeData = 0;
+ m_clipboard->emitChanged(QClipboard::Clipboard);
+ }
+ }
+
+private:
+ QBBClipboard * const m_clipboard;
+
+ QSet<QString> m_formatsToCheck;
+ QMimeData *m_userMimeData;
+};
QBBClipboard::QBBClipboard()
+ : m_mimeData(new MimeData(this))
{
- m_mimeData = 0;
}
QBBClipboard::~QBBClipboard()
@@ -70,46 +191,37 @@ void QBBClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (mode != QClipboard::Clipboard)
return;
- if (m_mimeData != data) {
- delete m_mimeData;
- m_mimeData = data;
- }
+ if (data == m_mimeData || data == m_mimeData->userMimeData())
+ return;
empty_clipboard();
+ m_mimeData->clear();
+ m_mimeData->setUserMimeData(data);
+
if (data == 0)
return;
- QStringList format = data->formats();
- for (int i = 0; i < format.size(); ++i) {
- QString type = format.at(i);
- QByteArray buf = data->data(type);
- if (!buf.size())
- continue;
-
- int ret = set_clipboard_data(type.toUtf8().data(), buf.size(), buf.data());
+ const QStringList formats = data->formats();
#if defined(QBBCLIPBOARD_DEBUG)
- qDebug() << "QBB: set " << type.toUtf8().data() << "to clipboard, size=" << buf.size() << ";ret=" << ret;
-#else
- Q_UNUSED(ret);
+ qDebug() << Q_FUNC_INFO << "formats=" << formats;
#endif
- }
-}
-void QBBClipboard::readClipboardBuff(const char *type)
-{
- char *pbuffer;
- if (is_clipboard_format_present(type) == 0) {
- int size = get_clipboard_data(type, &pbuffer);
- if (size != -1 && pbuffer) {
- QString qtype = type;
+ Q_FOREACH (const QString &format, formats) {
+ const QByteArray buf = data->data(format);
+
+ if (buf.isEmpty())
+ continue;
+
+ int ret = set_clipboard_data(format.toUtf8().data(), buf.size(), buf.data());
#if defined(QBBCLIPBOARD_DEBUG)
- qDebug() << "QBB: clipboard has " << qtype;
+ qDebug() << "QBB: set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret;
#endif
- m_mimeData->setData(qtype, QByteArray(pbuffer, size));
- delete pbuffer;
- }
+ if (ret)
+ m_mimeData->addFormatToCheck(format);
}
+
+ emitChanged(QClipboard::Clipboard);
}
QMimeData *QBBClipboard::mimeData(QClipboard::Mode mode)
@@ -117,16 +229,16 @@ QMimeData *QBBClipboard::mimeData(QClipboard::Mode mode)
if (mode != QClipboard::Clipboard)
return 0;
- if (!m_mimeData)
- m_mimeData = new QMimeData();
+ if (m_mimeData->userMimeData())
+ return m_mimeData->userMimeData();
m_mimeData->clear();
- for (int i = 0; i < 3; i++)
- readClipboardBuff(typeList[i]);
-
return m_mimeData;
}
QT_END_NAMESPACE
-#endif //QT_NO_CLIPBOAR
+
+#include "qbbclipboard.moc"
+
+#endif //QT_NO_CLIPBOARD
diff --git a/src/plugins/platforms/blackberry/qbbclipboard.h b/src/plugins/platforms/blackberry/qbbclipboard.h
index b9de9b3e36..11a36ba8e5 100644
--- a/src/plugins/platforms/blackberry/qbbclipboard.h
+++ b/src/plugins/platforms/blackberry/qbbclipboard.h
@@ -44,7 +44,6 @@
#ifndef QT_NO_CLIPBOARD
#include <QtGui/QPlatformClipboard>
-#include <QMimeData>
QT_BEGIN_NAMESPACE
@@ -57,8 +56,8 @@ public:
virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
private:
- QMimeData *m_mimeData;
- void readClipboardBuff(const char *type);
+ class MimeData;
+ MimeData *m_mimeData;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/blackberry/qbbscreen.cpp b/src/plugins/platforms/blackberry/qbbscreen.cpp
index 39d2136b7d..11e40f6150 100644
--- a/src/plugins/platforms/blackberry/qbbscreen.cpp
+++ b/src/plugins/platforms/blackberry/qbbscreen.cpp
@@ -286,7 +286,7 @@ void QBBScreen::updateHierarchy()
#endif
QList<QBBWindow*>::iterator it;
- int topZorder = 0;
+ int topZorder = 1; // root window is z-order 0, all "top" level windows are "above" it
for (it = ms_childWindows.begin(); it != ms_childWindows.end(); it++)
(*it)->updateZorder(topZorder);
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 45dd3525d5..ce87de2574 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -27,6 +27,7 @@ OBJECTIVE_SOURCES += main.mm \
qcocoafiledialoghelper.mm \
qcocoafontdialoghelper.mm \
qcocoacursor.mm \
+ qcocoasystemsettings.mm \
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
@@ -51,6 +52,7 @@ HEADERS += qcocoaintegration.h \
qcocoafiledialoghelper.h \
qcocoafontdialoghelper.h \
qcocoacursor.h \
+ qcocoasystemsettings.h \
FORMS += $$PWD/../../../widgets/dialogs/qfiledialog.ui
RESOURCES += qcocoaresources.qrc
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index be061547a9..5493b21c34 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -97,6 +97,7 @@ private:
QScopedPointer<QPlatformAccessibility> mAccessibility;
QScopedPointer<QPlatformTheme> mPlatformTheme;
+ QList<QCocoaScreen *> mScreens;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index fb8e487029..626a7fe0f9 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -134,6 +134,7 @@ QCocoaIntegration::QCocoaIntegration()
NSArray *screens = [NSScreen screens];
for (uint i = 0; i < [screens count]; i++) {
QCocoaScreen *screen = new QCocoaScreen(i);
+ mScreens.append(screen);
screenAdded(screen);
}
@@ -142,6 +143,11 @@ QCocoaIntegration::QCocoaIntegration()
QCocoaIntegration::~QCocoaIntegration()
{
[[NSApplication sharedApplication] setDelegate: 0];
+
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!mScreens.isEmpty()) {
+ delete mScreens.takeLast();
+ }
}
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 3a1f92fcf9..70e974161e 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -93,7 +93,6 @@ void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
// Load and instantiate nib file from temp
NSURL *nibUrl = [NSURL fileURLWithPath : QCFString::toNSString(nibDir)];
- [nibUrl autorelease];
NSNib *nib = [[NSNib alloc] initWithContentsOfURL : nibUrl];
[nib autorelease];
if(!nib) {
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.h b/src/plugins/platforms/cocoa/qcocoasystemsettings.h
new file mode 100644
index 0000000000..84a66d7193
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOASYSTEMSETTINGS_H
+#define QCOCOASYSTEMSETTINGS_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/qpalette.h>
+
+QT_BEGIN_NAMESPACE
+
+QPalette * qt_mac_createSystemPalette();
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
new file mode 100644
index 0000000000..5170c0bc8a
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoasystemsettings.h"
+
+#include <Carbon/Carbon.h>
+#include <QtCore/private/qcore_mac_p.h>
+
+QColor qt_mac_colorFromCGColor(CGColorRef cgcolor)
+{
+ QColor pc;
+ CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(cgcolor));
+ const CGFloat *components = CGColorGetComponents(cgcolor);
+ if (model == kCGColorSpaceModelRGB) {
+ pc.setRgbF(components[0], components[1], components[2], components[3]);
+ } else if (model == kCGColorSpaceModelCMYK) {
+ pc.setCmykF(components[0], components[1], components[2], components[3]);
+ } else if (model == kCGColorSpaceModelMonochrome) {
+ pc.setRgbF(components[0], components[0], components[0], components[1]);
+ } else {
+ // Colorspace we can't deal with.
+ qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model);
+ Q_ASSERT(false);
+ }
+ return pc;
+}
+
+QColor qt_mac_colorForTheme(ThemeBrush brush)
+{
+ QCFType<CGColorRef> cgClr = 0;
+ HIThemeBrushCreateCGColor(brush, &cgClr);
+ return qt_mac_colorFromCGColor(cgClr);
+}
+
+QColor qt_mac_colorForThemeTextColor(ThemeTextColor themeColor)
+{
+ // No GetThemeTextColor in 64-bit mode, use hardcoded values:
+ switch (themeColor) {
+ case kThemeTextColorAlertActive:
+ case kThemeTextColorTabFrontActive:
+ case kThemeTextColorBevelButtonActive:
+ case kThemeTextColorListView:
+ case kThemeTextColorPlacardActive:
+ case kThemeTextColorPopupButtonActive:
+ case kThemeTextColorPopupLabelActive:
+ case kThemeTextColorPushButtonActive:
+ return Qt::black;
+ case kThemeTextColorAlertInactive:
+ case kThemeTextColorDialogInactive:
+ case kThemeTextColorPlacardInactive:
+ return QColor(69, 69, 69, 255);
+ case kThemeTextColorPopupButtonInactive:
+ case kThemeTextColorPopupLabelInactive:
+ case kThemeTextColorPushButtonInactive:
+ case kThemeTextColorTabFrontInactive:
+ case kThemeTextColorBevelButtonInactive:
+ return QColor(127, 127, 127, 255);
+ default:
+ return QColor(0, 0, 0, 255); // ### TODO: Sample color like Qt 4.
+ }
+}
+
+QPalette * qt_mac_createSystemPalette()
+{
+ QColor qc;
+
+ // Standard palette initialization (copied from Qt 4 styles)
+ QColor background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
+ QColor light(background.lighter());
+ QColor dark(background.darker());
+ QColor mid(Qt::gray);
+ QPalette *palette = new QPalette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+
+ palette->setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette->setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette->setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette->setBrush(QPalette::Disabled, QPalette::Base, background);
+ palette->setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
+ palette->setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
+ palette->setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
+
+ // System palette initialization:
+ palette->setBrush( QPalette::Active, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushPrimaryHighlightColor) );
+ palette->setBrush( QPalette::Inactive, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor) );
+
+ palette->setBrush( QPalette::Disabled, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor) );
+ palette->setBrush( QPalette::Active, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonActiveDarkShadow) );
+
+ palette->setBrush( QPalette::Inactive, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonInactiveDarkShadow) );
+ palette->setBrush( QPalette::Disabled, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonInactiveDarkShadow) );
+
+ qc = qt_mac_colorForThemeTextColor(kThemeTextColorDialogActive);
+ palette->setColor(QPalette::Active, QPalette::Text, qc);
+ palette->setColor(QPalette::Active, QPalette::WindowText, qc);
+ palette->setColor(QPalette::Active, QPalette::HighlightedText, qc);
+
+ qc = qt_mac_colorForThemeTextColor(kThemeTextColorDialogInactive);
+ palette->setColor(QPalette::Inactive, QPalette::Text, qc);
+ palette->setColor(QPalette::Inactive, QPalette::WindowText, qc);
+ palette->setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
+ palette->setColor(QPalette::Disabled, QPalette::Text, qc);
+ palette->setColor(QPalette::Disabled, QPalette::WindowText, qc);
+ palette->setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
+ palette->setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
+ return palette;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index a7dc973937..fa235b6be0 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
+class QPalette;
class QCocoaTheme : public QPlatformTheme
{
public:
@@ -60,7 +61,11 @@ public:
bool usePlatformNativeDialog(DialogType dialogType) const;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const;
+ const QPalette *palette(Palette type = SystemPalette) const;
+
QVariant themeHint(ThemeHint hint) const;
+private:
+ mutable QPalette *m_systemPalette;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 0fef3234b4..6b0e04acf8 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -45,17 +45,19 @@
#include "qcocoacolordialoghelper.h"
#include "qcocoafiledialoghelper.h"
#include "qcocoafontdialoghelper.h"
+#include "qcocoasystemsettings.h"
QT_BEGIN_NAMESPACE
QCocoaTheme::QCocoaTheme()
+ :m_systemPalette(0)
{
}
QCocoaTheme::~QCocoaTheme()
{
-
+ delete m_systemPalette;
}
QPlatformMenu *QCocoaTheme::createPlatformMenu(QMenu *menu) const
@@ -102,6 +104,17 @@ QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialo
}
}
+const QPalette *QCocoaTheme::palette(Palette type) const
+{
+ if (type == SystemPalette) {
+ if (!m_systemPalette)
+ m_systemPalette = qt_mac_createSystemPalette();
+
+ return m_systemPalette;
+ }
+ return 0;
+}
+
QVariant QCocoaTheme::themeHint(ThemeHint hint) const
{
switch (hint) {
diff --git a/src/plugins/platforms/cocoa/qmacdefines_mac.h b/src/plugins/platforms/cocoa/qmacdefines_mac.h
index a35df47227..d89e313bcb 100644
--- a/src/plugins/platforms/cocoa/qmacdefines_mac.h
+++ b/src/plugins/platforms/cocoa/qmacdefines_mac.h
@@ -93,11 +93,6 @@ Yes, it is an informative comment ;-)
#include <QtCore/qglobal.h>
-#ifdef qDebug
-# define old_qDebug qDebug
-# undef qDebug
-#endif
-
#ifdef __LP64__
typedef signed int OSStatus;
#else
@@ -149,9 +144,3 @@ typedef AERecord AppleEvent;
#ifdef check
#undef check
#endif
-
-#ifdef old_qDebug
-# undef qDebug
-# define qDebug QT_NO_QDEBUG_MACRO
-# undef old_qDebug
-#endif
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index f16eff5449..6d7c89e086 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -59,15 +59,15 @@ QT_BEGIN_NAMESPACE
of QGuiApplication:
\list
- \o \c fontengine=native Indicates that the freetype font
+ \li \c fontengine=native Indicates that the freetype font
engine should not be used.
- \o \c gl=gdi Indicates that ARB Open GL functionality should not be used
+ \li \c gl=gdi Indicates that ARB Open GL functionality should not be used
\endlist
\section1 Tips
\list
- \o The environment variable \c QT_LIGHTHOUSE_WINDOWS_VERBOSE controls
+ \li The environment variable \c QT_LIGHTHOUSE_WINDOWS_VERBOSE controls
the debug level. It takes the form
\c{<keyword1>:<level1>,<keyword2>:<level2>}, where
keyword is one of \c integration, \c windows, \c backingstore and
diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp
index 3ef21fa0b7..1a8f593609 100644
--- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp
@@ -88,25 +88,54 @@
QT_BEGIN_NAMESPACE
-//#define DEBUG_SHOW_ATCLIENT_COMMANDS
-#ifdef DEBUG_SHOW_ATCLIENT_COMMANDS
+#ifndef QT_NO_DEBUG
QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdebug.h>
+# include <qdebug.h>
QT_END_INCLUDE_NAMESPACE
+static inline bool debug_accessibility()
+{
+ static signed int debugging = -1;
+ if (debugging == -1)
+ debugging = qgetenv("QT_DEBUG_ACCESSIBILITY").toInt();
+ return !!debugging;
+}
+# define accessibleDebug !debug_accessibility() ? (void)0 : qDebug
+#else
+# define accessibleDebug()
+#endif
-void showDebug(const char* funcName, const QAccessibleInterface *iface)
+//#define DEBUG_SHOW_ATCLIENT_COMMANDS
+#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
+void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface)
{
- qDebug() << "Role:" << qAccessibleRoleString(iface->role(0))
- << "Name:" << iface->text(QAccessible::Name, 0)
- << "State:" << QString::number(int(iface->state(0)), 16)
- << QLatin1String(funcName);
+ QString str;
+ QDebug dbg(&str);
+ dbg << iface << QLatin1String(funcName);
+ accessibleDebug("%s", qPrintable(str));
}
+# define accessibleDebugClientCalls(iface) accessibleDebugClientCalls_helper(Q_FUNC_INFO, iface)
#else
-# define showDebug(f, iface)
+# define accessibleDebugClientCalls(iface)
#endif
+
typedef QSharedPointer<QAccessibleInterface> QAIPointer;
+static bool compareAccessible(QAccessibleInterface *one, QAccessibleInterface *other)
+{
+ if (one == other) return true;
+ if (!one || !other) return false;
+
+ if (one->object() && other->object() && (one->object() == other->object()))
+ return true;
+ QAIPointer onePar(one->parent());
+ QAIPointer otherPar(other->parent());
+
+ if (compareAccessible(onePar.data(), otherPar.data()))
+ return onePar->indexOfChild(one) == otherPar->indexOfChild(other);
+ return false;
+}
+
// This stuff is used for widgets/items with no window handle:
typedef QMap<int, QPair<QObject*,int> > NotifyMap;
Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
@@ -595,7 +624,7 @@ IAccessible::accHitTest documents the value returned in pvarID like this:
HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -635,7 +664,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop,
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -659,7 +688,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *py
// moz: [important, but no need to implement up/down/left/right]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -799,7 +828,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT v
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -853,7 +882,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, I
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChildren)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -864,7 +893,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChil
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispParent)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -887,7 +916,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispPa
HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
{
Q_UNUSED(varID);
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -904,7 +933,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction)
{
Q_UNUSED(varID);
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -919,7 +948,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -944,7 +973,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID,
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -974,7 +1003,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelpTopic(BSTR *, VARIANT,
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut)
{
Q_UNUSED(varID);
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -1004,7 +1033,7 @@ static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAcce
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -1040,14 +1069,14 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* p
HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accName(VARIANT, BSTR)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
return DISP_E_MEMBERNOTFOUND;
}
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -1075,7 +1104,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIANT *pvarState)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -1151,7 +1180,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIAN
// moz: [important]
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR* pszValue)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid() || varID.lVal)
return E_FAIL;
@@ -1172,7 +1201,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR*
HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accValue(VARIANT, BSTR)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
return DISP_E_MEMBERNOTFOUND;
}
@@ -1181,7 +1210,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIAN
{
Q_UNUSED(flagsSelect);
Q_UNUSED(varID);
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -1207,24 +1236,43 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIAN
return res ? S_OK : S_FALSE;
}
-// moz: [important]
+/*!
+ \internal
+ Can return:
+
+ +-------------+------------------------------------------------------------------------------+
+ | VT_EMPTY | None. Neither this object nor any of its children has the keyboard focus. |
+ +-------------+------------------------------------------------------------------------------+
+ | VT_I4 | lVal is CHILDID_SELF. The object itself has the keyboard focus. |
+ +-------------+------------------------------------------------------------------------------+
+ | VT_I4 | lVal contains the child ID of the child element that has the keyboard focus. |
+ +-------------+------------------------------------------------------------------------------+
+ | VT_DISPATCH | pdispVal member is the address of the IDispatch interface for the child |
+ | | object that has the keyboard focus. |
+ +-------------+------------------------------------------------------------------------------+
+ moz: [important]
+*/
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
if (QAccessibleInterface *acc = accessible->focusChild()) {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- if (iface) {
+ if (compareAccessible(acc, accessible)) {
+ (*pvarID).vt = VT_I4;
+ (*pvarID).lVal = CHILDID_SELF;
+ delete acc;
+ return S_OK;
+ } else {
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+ IDispatch *iface = 0;
+ wacc->QueryInterface(IID_IDispatch, (void**)&iface);
(*pvarID).vt = VT_DISPATCH;
(*pvarID).pdispVal = iface;
return S_OK;
- } else {
- delete wacc;
}
+ delete acc;
}
(*pvarID).vt = VT_EMPTY;
return S_FALSE;
@@ -1232,7 +1280,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accSelection(VARIANT *pvarChildren)
{
- showDebug(__FUNCTION__, accessible);
+ accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 25b9336361..1239f3d8e2 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -366,10 +366,10 @@ void eatMouseMove()
There 2 types of native dialogs:
\list
- \o Dialogs provided by the Comdlg32 library (ChooseColor,
+ \li Dialogs provided by the Comdlg32 library (ChooseColor,
ChooseFont). They only provide a modal, blocking
function call (with idle processing).
- \o File dialogs are classes derived from IFileDialog. They
+ \li File dialogs are classes derived from IFileDialog. They
inherit IModalWindow and their exec() method (calling
IModalWindow::Show()) is similarly blocking, but methods
like close() can be called on them from event handlers.
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 9f2a1dc00c..d75752bc04 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -53,8 +53,11 @@
#include <QtGui/QPixmap>
#include <QtGui/QPainter>
#include <QtGui/QGuiApplication>
+#include <QtGui/private/qwindowsysteminterface_qpa_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
#include <QtCore/QPoint>
#include <shlobj.h>
@@ -300,14 +303,13 @@ private:
QWindowsDrag *m_drag;
Qt::MouseButtons m_currentButtons;
- Qt::DropAction m_currentAction;
ActionCursorMap m_cursors;
ULONG m_refs;
};
QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) :
- m_drag(drag), m_currentButtons(Qt::NoButton), m_currentAction(Qt::IgnoreAction),
+ m_drag(drag), m_currentButtons(Qt::NoButton),
m_refs(1)
{
if (QWindowsContext::verboseOLE)
@@ -321,24 +323,26 @@ QWindowsOleDropSource::~QWindowsOleDropSource()
qDebug("%s", __FUNCTION__);
}
+/*!
+ \brief Blend custom pixmap with cursors.
+*/
+
void QWindowsOleDropSource::createCursors()
{
- QDragManager *manager = QDragManager::self();
- if (!manager || !manager->object)
- return;
- const QPixmap pixmap = manager->object->pixmap();
+ const QDrag *drag = m_drag->currentDrag();
+ const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- if (!hasPixmap && manager->dragPrivate()->customCursors.isEmpty())
+ if (!hasPixmap)
return;
QList<Qt::DropAction> actions;
actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
if (hasPixmap)
actions << Qt::IgnoreAction;
- const QPoint hotSpot = manager->object->hotSpot();
+ const QPoint hotSpot = drag->hotSpot();
for (int cnum = 0; cnum < actions.size(); ++cnum) {
const Qt::DropAction action = actions.at(cnum);
- QPixmap cpm = manager->dragCursor(action);
+ QPixmap cpm = drag->dragCursor(action);
if (cpm.isNull())
cpm = m_drag->defaultCursor(action);
if (cpm.isNull()) {
@@ -361,7 +365,7 @@ void QWindowsOleDropSource::createCursors()
const QPoint newHotSpot = hotSpot;
QPixmap newCursor(w, h);
if (hasPixmap) {
- newCursor.fill(QColor(0, 0, 0, 0));
+ newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QRect srcRect = pixmap.rect();
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
@@ -375,7 +379,7 @@ void QWindowsOleDropSource::createCursors()
const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0;
if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY))
- m_cursors.insert(action, sysCursor);
+ m_cursors.insert(actions.at(cnum), sysCursor);
}
if (QWindowsContext::verboseOLE)
qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
@@ -432,7 +436,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
HRESULT hr = S_OK;
do {
- if (fEscapePressed || QWindowsDrag::instance()->dragBeingCancelled()) {
+ if (fEscapePressed) {
hr = ResultFromScode(DRAGDROP_S_CANCEL);
break;
}
@@ -461,13 +465,11 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
} while (false);
- QDragManager::self()->willDrop = hr == DRAGDROP_S_DROP;
-
if (QWindowsContext::verboseOLE
&& (QWindowsContext::verboseOLE > 1 || hr != S_OK))
- qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d willDrop = %d returns 0x%x",
+ qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d returns 0x%x",
__FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
- QDragManager::self()->willDrop, int(hr));
+ int(hr));
return hr;
}
@@ -479,16 +481,12 @@ QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
{
const Qt::DropAction action = translateToQDragDropAction(dwEffect);
+ m_drag->updateAction(action);
if (QWindowsContext::verboseOLE > 2)
qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action);
- if (m_currentAction != action) {
- m_currentAction = action;
- QDragManager::self()->emitActionChanged(m_currentAction);
- }
-
- const ActionCursorMap::const_iterator it = m_cursors.constFind(m_currentAction);
+ const ActionCursorMap::const_iterator it = m_cursors.constFind(action);
if (it != m_cursors.constEnd()) {
SetCursor(it.value());
return ResultFromScode(S_OK);
@@ -510,7 +508,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
*/
QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
- m_refs(1), m_window(w), m_currentWindow(0), m_chosenEffect(0), m_lastKeyState(0)
+ m_refs(1), m_window(w), m_chosenEffect(0), m_lastKeyState(0)
{
if (QWindowsContext::verboseOLE)
qDebug() << __FUNCTION__ << this << w;
@@ -558,6 +556,38 @@ QWindow *QWindowsOleDropTarget::findDragOverWindow(const POINTL &pt) const
return m_window;
}
+void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
+ const QPoint &point, LPDWORD pdwEffect)
+{
+ Q_ASSERT(window);
+ m_lastPoint = point;
+ m_lastKeyState = grfKeyState;
+
+ QWindowsDrag *windowsDrag = QWindowsDrag::instance();
+ const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
+ QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
+ QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+
+ const QPlatformDragQtResponse response =
+ QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
+
+ m_answerRect = response.answerRect();
+ const Qt::DropAction action = response.acceptedAction();
+ if (response.isAccepted()) {
+ m_chosenEffect = translateToWinDragEffects(action);
+ } else {
+ m_chosenEffect = DROPEFFECT_NONE;
+ }
+ *pdwEffect = m_chosenEffect;
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << m_window
+ << windowsDrag->dropData() << " supported actions=" << actions
+ << " mods=" << QGuiApplicationPrivate::modifier_buttons
+ << " mouse=" << QGuiApplicationPrivate::mouse_buttons
+ << " accepted: " << response.isAccepted() << action
+ << m_answerRect << " effect" << *pdwEffect;
+}
+
QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, LPDWORD pdwEffect)
@@ -567,124 +597,28 @@ QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
QWindowsDrag::instance()->setDropDataObject(pDataObj);
pDataObj->AddRef();
- m_currentWindow = m_window;
- sendDragEnterEvent(m_window, grfKeyState, pt, pdwEffect);
- *pdwEffect = m_chosenEffect;
+ const QPoint point = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
+ handleDrag(m_window, grfKeyState, point, pdwEffect);
return NOERROR;
}
-void QWindowsOleDropTarget::sendDragEnterEvent(QWindow *dragEnterWidget,
- DWORD grfKeyState,
- POINTL pt, LPDWORD pdwEffect)
-{
- Q_ASSERT(dragEnterWidget);
-
- m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dragEnterWidget, QPoint(pt.x,pt.y));
- m_lastKeyState = grfKeyState;
-
- m_chosenEffect = DROPEFFECT_NONE;
-
- QDragManager *manager = QDragManager::self();
- QMimeData *md = manager->dropData();
- const Qt::MouseButtons mouseButtons
- = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
- const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
- const Qt::KeyboardModifiers keyMods = toQtKeyboardModifiers(grfKeyState);
- QDragEnterEvent enterEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
- QGuiApplication::sendEvent(m_currentWindow, &enterEvent);
- m_answerRect = enterEvent.answerRect();
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << " sent drag enter to " << m_window
- << *md << " actions=" << actions
- << " mods=" << keyMods << " accepted: "
- << enterEvent.isAccepted();
-
- if (enterEvent.isAccepted())
- m_chosenEffect = translateToWinDragEffects(enterEvent.dropAction());
- // Documentation states that a drag move event is sent immediately after
- // a drag enter event. This will honor widgets overriding dragMoveEvent only:
- if (enterEvent.isAccepted()) {
- QDragMoveEvent moveEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
- m_answerRect = enterEvent.answerRect();
- moveEvent.setDropAction(enterEvent.dropAction());
- moveEvent.accept(); // accept by default, since enter event was accepted.
-
- QGuiApplication::sendEvent(dragEnterWidget, &moveEvent);
- if (moveEvent.isAccepted()) {
- m_answerRect = moveEvent.answerRect();
- m_chosenEffect = translateToWinDragEffects(moveEvent.dropAction());
- } else {
- m_chosenEffect = DROPEFFECT_NONE;
- }
- }
-}
-
QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
QWindow *dragOverWindow = findDragOverWindow(pt);
-
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, dragOverWindow, grfKeyState, pt.x, pt.y);
const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(dragOverWindow, QPoint(pt.x,pt.y));
// see if we should compress this event
if ((tmpPoint == m_lastPoint || m_answerRect.contains(tmpPoint))
&& m_lastKeyState == grfKeyState) {
*pdwEffect = m_chosenEffect;
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s: compressed event", __FUNCTION__);
return NOERROR;
}
- if (QWindowsContext::verboseOLE > 1)
- qDebug().nospace() << '>' << __FUNCTION__ << ' ' << m_window << " current "
- << dragOverWindow << " key=" << grfKeyState
- << " pt=" <<pt.x << ',' << pt.y;
-
- if (dragOverWindow != m_currentWindow) {
- QPointer<QWindow> dragOverWindowGuard(dragOverWindow);
- // Send drag leave event to the previous drag widget.
- // Drag-Over widget might be deleted in DragLeave,
- // (tasktracker 218353).
- QDragLeaveEvent dragLeave;
- if (m_currentWindow)
- QGuiApplication::sendEvent(m_currentWindow, &dragLeave);
- if (!dragOverWindowGuard) {
- dragOverWindow = findDragOverWindow(pt);
- }
- // Send drag enter event to the current drag widget.
- m_currentWindow = dragOverWindow;
- sendDragEnterEvent(dragOverWindow, grfKeyState, pt, pdwEffect);
- }
-
- QDragManager *manager = QDragManager::self();
- QMimeData *md = manager->dropData();
-
- const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
-
- QDragMoveEvent oldEvent(m_lastPoint, actions, md,
- QWindowsMouseHandler::keyStateToMouseButtons(m_lastKeyState),
- toQtKeyboardModifiers(m_lastKeyState));
-
- m_lastPoint = tmpPoint;
- m_lastKeyState = grfKeyState;
-
- QDragMoveEvent e(tmpPoint, actions, md,
- QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
- toQtKeyboardModifiers(grfKeyState));
- if (m_chosenEffect != DROPEFFECT_NONE) {
- if (oldEvent.dropAction() == e.dropAction() &&
- oldEvent.keyboardModifiers() == e.keyboardModifiers())
- e.setDropAction(translateToQDragDropAction(m_chosenEffect));
- e.accept();
- }
- QGuiApplication::sendEvent(dragOverWindow, &e);
-
- m_answerRect = e.answerRect();
- if (e.isAccepted())
- m_chosenEffect = translateToWinDragEffects(e.dropAction());
- else
- m_chosenEffect = DROPEFFECT_NONE;
- *pdwEffect = m_chosenEffect;
-
- if (QWindowsContext::verboseOLE > 1)
- qDebug("<%s effect=0x%lx", __FUNCTION__, m_chosenEffect);
+ handleDrag(dragOverWindow, grfKeyState, tmpPoint, pdwEffect);
return NOERROR;
}
@@ -694,9 +628,7 @@ QWindowsOleDropTarget::DragLeave()
if (QWindowsContext::verboseOLE)
qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
- m_currentWindow = 0;
- QDragLeaveEvent e;
- QGuiApplication::sendEvent(m_window, &e);
+ QWindowSystemInterface::handleDrag(m_window, 0, QPoint(), Qt::IgnoreAction);
QWindowsDrag::instance()->releaseDropDataObject();
return NOERROR;
@@ -724,21 +656,15 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
m_lastKeyState = grfKeyState;
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
- QDragManager *manager = QDragManager::self();
- QMimeData *md = manager->dropData();
- QDropEvent e(m_lastPoint, translateToQDragDropActions(*pdwEffect), md,
- QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
- toQtKeyboardModifiers(grfKeyState));
- if (m_chosenEffect != DROPEFFECT_NONE)
- e.setDropAction(translateToQDragDropAction(m_chosenEffect));
-
- QGuiApplication::sendEvent(dropWindow, &e);
- if (m_chosenEffect != DROPEFFECT_NONE)
- e.accept();
-
- if (e.isAccepted()) {
- if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) {
- if (e.dropAction() == Qt::MoveAction)
+
+ const QPlatformDropQtResponse response =
+ QWindowSystemInterface::handleDrop(dropWindow, windowsDrag->dropData(), m_lastPoint,
+ translateToQDragDropActions(*pdwEffect));
+
+ if (response.isAccepted()) {
+ const Qt::DropAction action = response.acceptedAction();
+ if (action == Qt::MoveAction || action == Qt::TargetMoveAction) {
+ if (action == Qt::MoveAction)
m_chosenEffect = DROPEFFECT_MOVE;
else
m_chosenEffect = DROPEFFECT_COPY;
@@ -760,7 +686,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
windowsDrag->dropDataObject()->SetData(&format, &medium, true);
}
} else {
- m_chosenEffect = translateToWinDragEffects(e.dropAction());
+ m_chosenEffect = translateToWinDragEffects(action);
}
} else {
m_chosenEffect = DROPEFFECT_NONE;
@@ -778,7 +704,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
\ingroup qt-lighthouse-win
*/
-QWindowsDrag::QWindowsDrag() : m_dropDataObject(0), m_dragBeingCancelled(false)
+QWindowsDrag::QWindowsDrag() : m_dropDataObject(0)
{
}
@@ -786,6 +712,17 @@ QWindowsDrag::~QWindowsDrag()
{
}
+/*!
+ \brief Return data for a drop in process. If it stems from a current drag, use a shortcut.
+*/
+
+QMimeData *QWindowsDrag::dropData()
+{
+ if (const QDrag *drag = currentDrag())
+ return drag->mimeData();
+ return &m_dropData;
+}
+
QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
{
switch (action) {
@@ -810,69 +747,46 @@ QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
return m_ignoreDragCursor;
}
-void QWindowsDrag::startDrag()
+Qt::DropAction QWindowsDrag::drag(QDrag *drag)
{
// TODO: Accessibility handling?
- QDragManager *dragManager = QDragManager::self();
- QMimeData *dropData = dragManager->dropData();
- m_dragBeingCancelled = false;
+ QMimeData *dropData = drag->mimeData();
+ Qt::DropAction dragResult = Qt::IgnoreAction;
DWORD resultEffect;
QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this);
windowDropSource->createCursors();
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
- const Qt::DropActions possibleActions = dragManager->possible_actions;
+ const Qt::DropActions possibleActions = drag->supportedActions();
const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
if (QWindowsContext::verboseOLE)
qDebug(">%s possible Actions=%x, effects=0x%lx", __FUNCTION__,
int(possibleActions), allowedEffects);
const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
- Qt::DropAction ret = Qt::IgnoreAction;
if (r == DRAGDROP_S_DROP) {
if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {
- ret = Qt::TargetMoveAction;
+ dragResult = Qt::TargetMoveAction;
resultEffect = DROPEFFECT_MOVE;
} else {
- ret = translateToQDragDropAction(resultEffect);
+ dragResult = translateToQDragDropAction(resultEffect);
}
// Force it to be a copy if an unsupported operation occurred.
// This indicates a bug in the drop target.
- if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects))
- ret = Qt::CopyAction;
- } else {
- dragManager->setCurrentTarget(0);
+ if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects)) {
+ qWarning("%s: Forcing Qt::CopyAction", __FUNCTION__);
+ dragResult = Qt::CopyAction;
+ }
}
-
// clean up
dropDataObject->releaseQt();
dropDataObject->Release(); // Will delete obj if refcount becomes 0
windowDropSource->Release(); // Will delete src if refcount becomes 0
if (QWindowsContext::verboseOLE)
qDebug("<%s allowedEffects=0x%lx, reportedPerformedEffect=0x%lx, resultEffect=0x%lx, hr=0x%x, dropAction=%d",
- __FUNCTION__, allowedEffects, reportedPerformedEffect, resultEffect, int(r), ret);
-}
-
-void QWindowsDrag::move(const QMouseEvent *me)
-{
- const QPoint pos = me->pos();
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
-}
-
-void QWindowsDrag::drop(const QMouseEvent *me)
-{
- const QPoint pos = me->pos();
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
-}
-
-void QWindowsDrag::cancel()
-{
- // TODO: Accessibility handling?
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
- m_dragBeingCancelled = true;
+ __FUNCTION__, allowedEffects, reportedPerformedEffect,
+ resultEffect, int(r), dragResult);
+ return dragResult;
}
QWindowsDrag *QWindowsDrag::instance()
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index 86b5539f92..7b629baccc 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -45,9 +45,9 @@
#include "qwindowsinternalmimedata.h"
#include <QtGui/QPlatformDrag>
+#include <QtGui/QPixmap>
QT_BEGIN_NAMESPACE
-
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
QWindowsDropMimeData() {}
@@ -73,11 +73,10 @@ public:
private:
inline QWindow *findDragOverWindow(const POINTL &pt) const;
- void sendDragEnterEvent(QWindow *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ void handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &, LPDWORD pdwEffect);
ULONG m_refs;
QWindow *const m_window;
- QWindow *m_currentWindow;
QRect m_answerRect;
QPoint m_lastPoint;
DWORD m_chosenEffect;
@@ -92,25 +91,20 @@ public:
virtual QMimeData *platformDropData() { return &m_dropData; }
- virtual void startDrag();
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
- virtual void cancel();
+ virtual Qt::DropAction drag(QDrag *drag);
static QWindowsDrag *instance();
IDataObject *dropDataObject() const { return m_dropDataObject; }
void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
void releaseDropDataObject();
-
- bool dragBeingCancelled() const { return m_dragBeingCancelled; }
+ QMimeData *dropData();
QPixmap defaultCursor(Qt::DropAction action) const;
private:
QWindowsDropMimeData m_dropData;
IDataObject *m_dropDataObject;
- bool m_dragBeingCancelled;
mutable QPixmap m_copyDragCursor;
mutable QPixmap m_moveDragCursor;
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 5085dfefb7..ae5053210e 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -108,11 +108,11 @@ template <class T>
\section1 Testing
\list
- \o Install the East Asian language support and choose Japanese (say).
- \o Compile the \a mainwindows/mdi example and open a text window.
- \o In the language bar, switch to Japanese and choose the
+ \li Install the East Asian language support and choose Japanese (say).
+ \li Compile the \a mainwindows/mdi example and open a text window.
+ \li In the language bar, switch to Japanese and choose the
Input method 'Hiragana'.
- \o In a text editor control, type the syllable \a 'la'.
+ \li In a text editor control, type the syllable \a 'la'.
Underlined characters show up, indicating that there is completion
available. Press the Space key two times. A completion popup occurs
which shows the options.
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 3e98be4741..b43362c045 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -74,9 +74,9 @@ QT_BEGIN_NAMESPACE
Currently implemented keys
\list
- \o handle (HWND)
- \o getDC (DC)
- \o releaseDC Releases the previously acquired DC and returns 0.
+ \li handle (HWND)
+ \li getDC (DC)
+ \li releaseDC Releases the previously acquired DC and returns 0.
\endlist
\ingroup qt-lighthouse-win
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 570e4b3b6b..e41db3f60f 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -413,14 +413,14 @@ static bool canGetData(int cf, IDataObject * pDataObj)
Qt has predefined support for the following Windows Clipboard formats:
\table
- \header \o Windows Format \o Equivalent MIME type
- \row \o \c CF_UNICODETEXT \o \c text/plain
- \row \o \c CF_TEXT \o \c text/plain
- \row \o \c CF_DIB \o \c{image/xyz}, where \c xyz is
+ \header \li Windows Format \li Equivalent MIME type
+ \row \li \c CF_UNICODETEXT \li \c text/plain
+ \row \li \c CF_TEXT \li \c text/plain
+ \row \li \c CF_DIB \li \c{image/xyz}, where \c xyz is
a \l{QImageWriter::supportedImageFormats()}{Qt image format}
- \row \o \c CF_HDROP \o \c text/uri-list
- \row \o \c CF_INETURL \o \c text/uri-list
- \row \o \c CF_HTML \o \c text/html
+ \row \li \c CF_HDROP \li \c text/uri-list
+ \row \li \c CF_INETURL \li \c text/uri-list
+ \row \li \c CF_HTML \li \c text/html
\endtable
An example use of this class would be to map the Windows Metafile
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 3ae9fe1048..6f34967ee8 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -63,11 +63,11 @@ QT_BEGIN_NAMESPACE
The following methods are NOT supported for data transfer using the
clipboard or drag-drop:
\list
- \o IDataObject::SetData -- return E_NOTIMPL
- \o IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
- \o ::DUnadvise
- \o ::EnumDAdvise
- \o IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
+ \li IDataObject::SetData -- return E_NOTIMPL
+ \li IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
+ \li ::DUnadvise
+ \li ::EnumDAdvise
+ \li IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
(NOTE: must set pformatetcOut->ptd = NULL)
\endlist
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 436cc2c0d9..77a327a62a 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -115,7 +115,11 @@ public:
QWindowsScreenManager();
- inline void clearScreens() { qDeleteAll(m_screens); m_screens.clear(); }
+ inline void clearScreens() {
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
+ }
void handleScreenChanges();
bool handleDisplayChange(WPARAM wParam, LPARAM lParam);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 3e0bec8d46..b2ebe06a58 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -205,18 +205,18 @@ static bool shouldShowMaximizeButton(Qt::WindowFlags flags)
Window creation is split in 3 steps:
\list
- \o fromWindow() Gather all required information
- \o create() Create the system handle.
- \o initialize() Post creation initialization steps.
+ \li fromWindow() Gather all required information
+ \li create() Create the system handle.
+ \li initialize() Post creation initialization steps.
\endlist
The reason for this split is to also enable changing the QWindowFlags
by calling:
\list
- \o fromWindow() Gather information and determine new system styles
- \o applyWindowFlags() to apply the new window system styles.
- \o initialize() Post creation initialization steps.
+ \li fromWindow() Gather information and determine new system styles
+ \li applyWindowFlags() to apply the new window system styles.
+ \li initialize() Post creation initialization steps.
\endlist
Contains the window creation code formerly in qwidget_win.cpp.
@@ -594,13 +594,13 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
\brief Raster or OpenGL Window.
\list
- \o Raster type: handleWmPaint() is implemented to
+ \li Raster type: handleWmPaint() is implemented to
to bitblt the image. The DC can be accessed
via getDC/Relase DC, which has a special handling
when within a paint event (in that case, the DC obtained
from BeginPaint() is returned).
- \o Open GL: The first time QWindowsGLContext accesses
+ \li Open GL: The first time QWindowsGLContext accesses
the handle, it sets up the pixelformat on the DC
which in turn sets it on the window (see flag
PixelFormatInitialized).
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index ab802ced27..17e8bb53eb 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,6 +1,6 @@
Required packages:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev
+libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev
On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev
+libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev
The packages for xcb-render-util can be installed manually from http://packages.ubuntu.com/natty/libxcb-render-util0 and http://packages.ubuntu.com/natty/libxcb-render-util0-dev
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index f8d35ed4da..63ce73993f 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -74,7 +74,7 @@ public:
break;
default:
- qWarning("QTestLiteMime: Internal error: Unsupported clipboard mode");
+ qWarning("QXcbClipboardMime: Internal error: Unsupported clipboard mode");
break;
}
}
@@ -209,7 +209,7 @@ QXcbClipboard::~QXcbClipboard()
// waiting until the clipboard manager fetches the content.
if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, clipboard_timeout, true)) {
- qWarning("QClipboard: Unable to receive an event from the "
+ qWarning("QXcbClipboard: Unable to receive an event from the "
"clipboard manager in a reasonable time");
}
}
@@ -292,7 +292,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());
if (getSelectionOwner(modeAtom) != newOwner) {
- qWarning("QClipboard::setData: Cannot set X11 selection owner");
+ qWarning("QXcbClipboard::setData: Cannot set X11 selection owner");
}
emitChanged(mode);
@@ -403,7 +403,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win
atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);
// (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment);
- qWarning() << "not implemented INCR just YET!";
+ qWarning("QXcbClipboard: INCR is unimplemented");
return property;
}
@@ -445,7 +445,7 @@ void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *eve
void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
{
if (requestor() && req->requestor == requestor()) {
- qDebug() << "This should be caught before";
+ qWarning("QXcbClipboard: Selection request should be caught before");
return;
}
@@ -460,7 +460,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
QMimeData *d;
QClipboard::Mode mode = modeForAtom(req->selection);
if (mode > QClipboard::Selection) {
- qWarning() << "QClipboard: Unknown selection" << connection()->atomName(req->selection);
+ qWarning() << "QXcbClipboard: Unknown selection" << connection()->atomName(req->selection);
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
@@ -468,14 +468,14 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
d = m_clientClipboard[mode];
if (!d) {
- qWarning("QClipboard: Cannot transfer data, no data available");
+ qWarning("QXcbClipboard: Cannot transfer data, no data available");
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
if (m_timestamp[mode] == XCB_CURRENT_TIME // we don't own the selection anymore
|| (req->time != XCB_CURRENT_TIME && req->time < m_timestamp[mode])) {
- qDebug("QClipboard: SelectionRequest too old");
+ qWarning("QXcbClipboard: SelectionRequest too old");
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
@@ -530,7 +530,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
property, XCB_ATOM_INTEGER, 32, 1, &m_timestamp[mode]);
ret = property;
} else {
- qWarning("QClipboard: Invalid data timestamp");
+ qWarning("QXcbClipboard: Invalid data timestamp");
}
} else if (target == xa_targets) {
ret = sendTargetsSelection(d, req->requestor, property);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index fdc2c76fea..367b24da9d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -109,6 +109,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
, m_has_support_for_dri2(false)
#endif
, xfixes_first_event(0)
+ , has_shape_extension(false)
+ , has_input_shape(false)
{
m_primaryScreen = 0;
@@ -133,7 +135,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
#endif //XCB_USE_XLIB
if (!m_connection || xcb_connection_has_error(m_connection))
- qFatal("Could not connect to display %s", m_displayName.constData());
+ qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData());
m_reader = new QXcbEventReader(this);
#ifdef XCB_POLL_FOR_QUEUED_EVENT
@@ -175,6 +177,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
#ifdef XCB_USE_XINPUT2_MAEMO
initializeXInput2();
#endif
+ initializeXShape();
m_wmSupport.reset(new QXcbWMSupport(this));
m_keyboard = new QXcbKeyboard(this);
@@ -191,7 +194,9 @@ QXcbConnection::~QXcbConnection()
{
delete m_clipboard;
- qDeleteAll(m_screens);
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
#ifdef XCB_USE_XINPUT2_MAEMO
finalizeXInput2();
@@ -250,7 +255,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
#ifdef XCB_EVENT_DEBUG
#define PRINT_XCB_EVENT(ev) \
case ev: \
- qDebug("%s: %d - %s - sequence: %d", message, int(ev), #ev, event->sequence); \
+ qDebug("QXcbConnection: %s: %d - %s - sequence: %d", message, int(ev), #ev, event->sequence); \
break;
switch (event->response_type & ~0x80) {
@@ -287,7 +292,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
default:
- qDebug("%s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence));
+ qDebug("QXcbConnection: %s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence));
}
#else
Q_UNUSED(message);
@@ -460,7 +465,7 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
- qDebug("XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+ qWarning("QXcbConnection: XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
int(error->error_code), xcb_errors[clamped_error_code],
int(error->sequence), int(error->resource_id),
int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
@@ -552,7 +557,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
case XCB_SELECTION_NOTIFY:
setTime(((xcb_selection_notify_event_t *)event)->time);
- qDebug() << "XCB_SELECTION_NOTIFY";
handled = false;
break;
case XCB_PROPERTY_NOTIFY:
@@ -714,9 +718,9 @@ void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *
return;
if (event->type == atom(QXcbAtom::XdndStatus)) {
- drag()->handleStatus(event, false);
+ drag()->handleStatus(event);
} else if (event->type == atom(QXcbAtom::XdndFinished)) {
- drag()->handleFinished(event, false);
+ drag()->handleFinished(event);
}
QXcbWindow *window = platformWindowFromId(event->window);
@@ -1024,7 +1028,7 @@ void QXcbConnection::initializeXFixes()
xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
xfixes_query_cookie, &error);
if (!xfixes_query || error || xfixes_query->major_version < 2) {
- qWarning("Failed to initialize XFixes");
+ qWarning("QXcbConnection: Failed to initialize XFixes");
free(error);
xfixes_first_event = 0;
}
@@ -1041,13 +1045,32 @@ void QXcbConnection::initializeXRender()
xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection,
xrender_query_cookie, &error);
if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) {
- qWarning("Failed to initialize XRender");
+ qWarning("QXcbConnection: Failed to initialize XRender");
free(error);
}
free(xrender_query);
#endif
}
+void QXcbConnection::initializeXShape()
+{
+ const xcb_query_extension_reply_t *xshape_reply = xcb_get_extension_data(m_connection, &xcb_shape_id);
+ if (!xshape_reply || !xshape_reply->present)
+ return;
+
+ has_shape_extension = true;
+ xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version(m_connection);
+ xcb_shape_query_version_reply_t *shape_query = xcb_shape_query_version_reply(m_connection,
+ cookie, NULL);
+ if (!shape_query) {
+ qWarning("QXcbConnection: Failed to initialize SHAPE extension");
+ } else if (shape_query->major_version > 1 || (shape_query->major_version == 1 && shape_query->minor_version >= 1)) {
+ // The input shape is the only thing added in SHAPE 1.1
+ has_input_shape = true;
+ }
+ free(shape_query);
+}
+
#if defined(XCB_USE_EGL)
bool QXcbConnection::hasEgl() const
{
@@ -1066,7 +1089,7 @@ void QXcbConnection::initializeDri2()
connect_cookie, NULL);
if (! connect || connect->driver_name_length + connect->device_name_length == 0) {
- qDebug() << "Failed to connect to dri2";
+ qWarning("QXcbConnection: Failed to connect to DRI2");
return;
}
@@ -1076,14 +1099,14 @@ void QXcbConnection::initializeDri2()
int fd = open(m_dri2_device_name.constData(), O_RDWR);
if (fd < 0) {
- qDebug() << "InitializeDri2: Could'nt open device << dri2DeviceName";
+ qWarning() << "QXcbConnection: Couldn't open DRI2 device" << m_dri2_device_name;
m_dri2_device_name = QByteArray();
return;
}
drm_magic_t magic;
if (drmGetMagic(fd, &magic)) {
- qDebug() << "Failed to get drmMagic";
+ qWarning("QXcbConnection: Failed to get drmMagic");
return;
}
@@ -1092,7 +1115,7 @@ void QXcbConnection::initializeDri2()
xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,
authenticate_cookie, NULL);
if (authenticate == NULL || !authenticate->authenticated) {
- qWarning("DRI2: failed to authenticate");
+ qWarning("QXcbConnection: DRI2: failed to authenticate");
free(authenticate);
return;
}
@@ -1101,14 +1124,14 @@ void QXcbConnection::initializeDri2()
EGLDisplay display = eglGetDRMDisplayMESA(fd);
if (!display) {
- qWarning("failed to create display");
+ qWarning("QXcbConnection: Failed to create EGL display using DRI2");
return;
}
m_egl_display = display;
EGLint major,minor;
if (!eglInitialize(display, &major, &minor)) {
- qWarning("failed to initialize display");
+ qWarning("QXcbConnection: Failed to initialize EGL display using DRI2");
return;
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 7beb41bdd7..34943bfdef 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -354,6 +354,8 @@ public:
inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
bool hasXFixes() const { return xfixes_first_event > 0; }
+ bool hasXShape() const { return has_shape_extension; }
+ bool hasInputShape() const { return has_input_shape; }
private slots:
void processXcbEvents();
@@ -363,6 +365,7 @@ private:
void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
void initializeXFixes();
void initializeXRender();
+ void initializeXShape();
#ifdef XCB_USE_DRI2
void initializeDri2();
#endif
@@ -429,6 +432,9 @@ private:
QVector<PeekFunc> m_peekFuncs;
uint32_t xfixes_first_event;
+
+ bool has_shape_extension;
+ bool has_input_shape;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index e928fe2d0a..3aeaaba2d8 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -52,6 +52,12 @@
#include <qevent.h>
#include <qguiapplication.h>
#include <qrect.h>
+#include <qpainter.h>
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtPlatformSupport/private/qshapedpixmapdndwindow_p.h>
+#include <QtPlatformSupport/private/qsimpledrag_p.h>
QT_BEGIN_NAMESPACE
@@ -109,12 +115,11 @@ static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
return proxy;
}
-
-class QDropData : public QXcbMime
+class QXcbDropData : public QXcbMime
{
public:
- QDropData(QXcbDrag *d);
- ~QDropData();
+ QXcbDropData(QXcbDrag *d);
+ ~QXcbDropData();
protected:
bool hasFormat_sys(const QString &mimeType) const;
@@ -127,10 +132,9 @@ protected:
};
-QXcbDrag::QXcbDrag(QXcbConnection *c)
- : QXcbObject(c)
+QXcbDrag::QXcbDrag(QXcbConnection *c) : QXcbObject(c)
{
- dropData = new QDropData(this);
+ dropData = new QXcbDropData(this);
init();
heartbeat = -1;
@@ -147,13 +151,13 @@ void QXcbDrag::init()
{
currentWindow.clear();
+ accepted_drop_action = Qt::IgnoreAction;
+
xdnd_dragsource = XCB_NONE;
- last_target_accepted_action = Qt::IgnoreAction;
waiting_for_status = false;
current_target = XCB_NONE;
current_proxy_target = XCB_NONE;
- xdnd_dragging = false;
source_time = XCB_CURRENT_TIME;
target_time = XCB_CURRENT_TIME;
@@ -169,16 +173,17 @@ QMimeData *QXcbDrag::platformDropData()
void QXcbDrag::startDrag()
{
+ // #fixme enableEventFilter();
+
init();
heartbeat = startTimer(200);
- xdnd_dragging = true;
+
xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
atom(QXcbAtom::XdndSelection), connection()->time());
- QDragManager *manager = QDragManager::self();
- QStringList fmts = QXcbMime::formatsHelper(manager->dropData());
+ QStringList fmts = QXcbMime::formatsHelper(drag()->mimeData());
for (int i = 0; i < fmts.size(); ++i) {
QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
for (int j = 0; j < atoms.size(); ++j) {
@@ -190,23 +195,16 @@ void QXcbDrag::startDrag()
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
atom(QXcbAtom::XdndTypelist),
XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
-
- QPointF pos = QCursor::pos();
- QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
- move(&me);
-
-// if (!QWidget::mouseGrabber())
-// manager->shapedPixmapWindow->grabMouse();
+ QBasicDrag::startDrag();
}
void QXcbDrag::endDrag()
{
- Q_ASSERT(heartbeat != -1);
- killTimer(heartbeat);
- heartbeat = -1;
-
- xdnd_dragging = false;
+ if (heartbeat != -1) {
+ killTimer(heartbeat);
+ heartbeat = -1;
+ }
+ QBasicDrag::endDrag();
}
static xcb_translate_coordinates_reply_t *
@@ -217,9 +215,29 @@ translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int
return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
}
+static
+bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, xcb_shape_sk_t shapeType)
+{
+ bool interacts = true;
+ xcb_shape_get_rectangles_reply_t *reply = xcb_shape_get_rectangles_reply(connection, xcb_shape_get_rectangles(connection, w, shapeType), NULL);
+ if (reply) {
+ xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply);
+ if (rectangles) {
+ interacts = false;
+ const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply);
+ for (int i = 0; !interacts && i < nRectangles; ++i) {
+ interacts = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos);
+ }
+ }
+ free(reply);
+ }
+
+ return interacts;
+}
+
xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md)
{
- if (w == QDragManager::self()->shapedPixmapWindow->handle()->winId())
+ if (w == shapedPixmapWindow()->handle()->winId())
return 0;
if (md) {
@@ -244,22 +262,12 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
bool isAware = reply && reply->type != XCB_NONE;
free(reply);
if (isAware) {
- xcb_xfixes_region_t region = xcb_generate_id(xcb_connection());
- xcb_xfixes_create_region_from_window(xcb_connection(), region, w, XCB_SHAPE_SK_BOUNDING);
- xcb_xfixes_fetch_region_reply_t *reply = xcb_xfixes_fetch_region_reply(xcb_connection(), xcb_xfixes_fetch_region(xcb_connection(), region), NULL);
- if (reply) {
- xcb_rectangle_t *rectangles = xcb_xfixes_fetch_region_rectangles(reply);
- if (rectangles) {
- windowContainsMouse = false;
- const int nRectangles = xcb_xfixes_fetch_region_rectangles_length(reply);
- for (int i = 0; !windowContainsMouse && i < nRectangles; ++i) {
- windowContainsMouse = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos);
- }
- }
- free(reply);
- }
- xcb_xfixes_destroy_region(xcb_connection(), region);
-
+ // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we
+ // need to check both here so that in the case one is set and the other is not we still get the correct result.
+ if (connection()->hasInputShape())
+ windowContainsMouse = windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_INPUT);
+ if (windowContainsMouse && connection()->hasXShape())
+ windowContainsMouse = windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_BOUNDING);
if (windowContainsMouse)
return w;
}
@@ -296,9 +304,7 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
void QXcbDrag::move(const QMouseEvent *me)
{
- DEBUG() << "QDragManager::move enter" << me->globalPos();
-
- // ###
+ QBasicDrag::move(me);
QPoint globalPos = me->globalPos();
if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
@@ -337,15 +343,13 @@ void QXcbDrag::move(const QMouseEvent *me)
::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate)
return;
+
xcb_window_t target = translate->child;
int lx = translate->dst_x;
int ly = translate->dst_y;
free (translate);
- if (target == rootwin) {
- // Ok.
- } else if (target) {
- //me
+ if (target && target != rootwin) {
xcb_window_t src = rootwin;
while (target != 0) {
DNDDEBUG << "checking target for XdndAware" << target << lx << ly;
@@ -376,7 +380,7 @@ void QXcbDrag::move(const QMouseEvent *me)
target = child;
}
- if (!target || target == QDragManager::self()->shapedPixmapWindow->handle()->winId()) {
+ if (!target || target == shapedPixmapWindow()->handle()->winId()) {
DNDDEBUG << "need to find real window";
target = findRealWindow(globalPos, rootwin, 6);
DNDDEBUG << "real window found" << target;
@@ -393,9 +397,6 @@ void QXcbDrag::move(const QMouseEvent *me)
target = rootwin;
}
- DNDDEBUG << "and the final target is " << target;
- DNDDEBUG << "the widget w is" << (w ? w->window() : 0);
-
xcb_window_t proxy_target = xdndProxy(connection(), target);
if (!proxy_target)
proxy_target = target;
@@ -414,7 +415,6 @@ void QXcbDrag::move(const QMouseEvent *me)
free(reply);
}
- DEBUG() << "target=" << target << "current_target=" << current_target;
if (target != current_target) {
if (current_target)
send_leave();
@@ -447,11 +447,10 @@ void QXcbDrag::move(const QMouseEvent *me)
waiting_for_status = false;
}
}
+
if (waiting_for_status)
return;
- QDragManager *m = QDragManager::self();
-
if (target) {
waiting_for_status = true;
@@ -465,28 +464,21 @@ void QXcbDrag::move(const QMouseEvent *me)
move.data.data32[1] = 0; // flags
move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
move.data.data32[3] = connection()->time();
- move.data.data32[4] = toXdndAction(m->defaultAction(m->dragPrivate()->possible_actions, QGuiApplication::keyboardModifiers()));
+ move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), QGuiApplication::keyboardModifiers()));
DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
source_time = connection()->time();
if (w)
- handle_xdnd_position(w->window(), &move, false);
+ handle_xdnd_position(w->window(), &move);
else
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
- } else {
- if (m->willDrop) {
- m->willDrop = false;
- }
}
- m->updateCursor();
- DEBUG() << "QDragManager::move leave";
}
-void QXcbDrag::drop(const QMouseEvent *)
+void QXcbDrag::drop(const QMouseEvent *event)
{
- endDrag();
-
+ QBasicDrag::drop(event);
if (!current_target)
return;
@@ -500,14 +492,13 @@ void QXcbDrag::drop(const QMouseEvent *)
drop.data.data32[2] = connection()->time();
drop.data.data32[3] = 0;
- drop.data.data32[4] = 0;
+ drop.data.data32[4] = currentDrag()->supportedActions();
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
- QDragManager *manager = QDragManager::self();
Transaction t = {
connection()->time(),
@@ -515,21 +506,22 @@ void QXcbDrag::drop(const QMouseEvent *)
current_proxy_target,
(w ? w->window() : 0),
// current_embedding_widget,
- manager->object
+ currentDrag()
};
transactions.append(t);
restartDropExpiryTimer();
- if (w)
- handleDrop(w->window(), &drop, false);
- else
+ if (w) {
+ handleDrop(w->window(), &drop);
+ } else {
xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
+ }
current_target = 0;
current_proxy_target = 0;
source_time = 0;
// current_embedding_widget = 0;
- manager->object = 0;
+ // #fixme resetDndState(false);
}
Qt::DropAction QXcbDrag::toDropAction(xcb_atom_t a) const
@@ -719,7 +711,7 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev
DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
}
-void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e, bool passive)
+void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e)
{
QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
Q_ASSERT(w);
@@ -727,11 +719,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
p -= geometry.topLeft();
- // ####
-// if (!passive && checkEmbedded(w, e))
-// return;
-
- if (!w || (/*!w->acceptDrops() &&*/ (w->windowType() == Qt::Desktop)))
+ if (!w || (w->windowType() == Qt::Desktop))
return;
if (e->data.data32[0] != xdnd_dragsource) {
@@ -739,12 +727,27 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
return;
}
+ currentPosition = p;
+ currentWindow = w;
+
// timestamp from the source
- if (e->data.data32[3] != XCB_NONE)
- target_time /*= X11->userTime*/ = e->data.data32[3];
+ if (e->data.data32[3] != XCB_NONE) {
+ target_time = e->data.data32[3];
+ }
- QDragManager *manager = QDragManager::self();
- QMimeData *dropData = manager->dropData();
+ QMimeData *dropData = 0;
+ Qt::DropActions supported_actions = Qt::IgnoreAction;
+ if (currentDrag()) {
+ dropData = currentDrag()->mimeData();
+ supported_actions = currentDrag()->supportedActions();
+ } else {
+ dropData = platformDropData();
+ supported_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
+ }
+
+ QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w,dropData,p,supported_actions);
+ QRect answerRect(p + geometry.topLeft(), QSize(1,1));
+ answerRect = qt_response.answerRect().translated(geometry.topLeft()).intersected(geometry);
xcb_client_message_event_t response;
response.response_type = XCB_CLIENT_MESSAGE;
@@ -752,83 +755,33 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
response.format = 32;
response.type = atom(QXcbAtom::XdndStatus);
response.data.data32[0] = xcb_window(w);
- response.data.data32[1] = 0; // flags
+ response.data.data32[1] = qt_response.isAccepted(); // flags
response.data.data32[2] = 0; // x, y
response.data.data32[3] = 0; // w, h
- response.data.data32[4] = 0; // action
+ response.data.data32[4] = toXdndAction(qt_response.acceptedAction()); // action
- if (!passive) { // otherwise just reject
- QRect answerRect(p + geometry.topLeft(), QSize(1,1));
- if (manager->object) {
- manager->possible_actions = manager->dragPrivate()->possible_actions;
- } else {
- manager->possible_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
- }
- QDragMoveEvent me(p, manager->possible_actions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
-
- Qt::DropAction accepted_action = Qt::IgnoreAction;
-
- currentPosition = p;
-
- if (w != currentWindow.data()) {
- if (currentWindow) {
- QDragLeaveEvent e;
- QGuiApplication::sendEvent(currentWindow.data(), &e);
- }
- currentWindow = w;
-
- last_target_accepted_action = Qt::IgnoreAction;
- QDragEnterEvent de(p, manager->possible_actions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
- QGuiApplication::sendEvent(w, &de);
- if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
- last_target_accepted_action = de.dropAction();
- }
- DEBUG() << "qt_handle_xdnd_position action=" << connection()->atomName(e->data.data32[4]);
+ if (answerRect.left() < 0)
+ answerRect.setLeft(0);
+ if (answerRect.right() > 4096)
+ answerRect.setRight(4096);
+ if (answerRect.top() < 0)
+ answerRect.setTop(0);
+ if (answerRect.bottom() > 4096)
+ answerRect.setBottom(4096);
+ if (answerRect.width() < 0)
+ answerRect.setWidth(0);
+ if (answerRect.height() < 0)
+ answerRect.setHeight(0);
- if (last_target_accepted_action != Qt::IgnoreAction) {
- me.setDropAction(last_target_accepted_action);
- me.accept();
- }
- QGuiApplication::sendEvent(w, &me);
- if (me.isAccepted()) {
- response.data.data32[1] = 1; // yes
- accepted_action = me.dropAction();
- last_target_accepted_action = accepted_action;
- } else {
- response.data.data32[0] = 0;
- last_target_accepted_action = Qt::IgnoreAction;
- }
- answerRect = me.answerRect().translated(geometry.topLeft()).intersected(geometry);
-
- if (answerRect.left() < 0)
- answerRect.setLeft(0);
- if (answerRect.right() > 4096)
- answerRect.setRight(4096);
- if (answerRect.top() < 0)
- answerRect.setTop(0);
- if (answerRect.bottom() > 4096)
- answerRect.setBottom(4096);
- if (answerRect.width() < 0)
- answerRect.setWidth(0);
- if (answerRect.height() < 0)
- answerRect.setHeight(0);
-
-// response.data.data32[2] = (answerRect.x() << 16) + answerRect.y();
-// response.data.data32[3] = (answerRect.width() << 16) + answerRect.height();
- response.data.data32[4] = toXdndAction(accepted_action);
- }
+ response.data.data32[4] = toXdndAction(qt_response.acceptedAction());
// reset
target_time = XCB_CURRENT_TIME;
- DEBUG() << "sending XdndStatus" << (xdnd_dragsource == connection()->clipboard()->owner()) << xdnd_dragsource
- << response.data.data32[1] << connection()->atomName(response.data.data32[4]);
if (xdnd_dragsource == connection()->clipboard()->owner())
- handle_xdnd_status(&response, passive);
+ handle_xdnd_status(&response);
else
Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
XCB_EVENT_MASK_NO_EVENT, (const char *)&response));
@@ -850,7 +803,7 @@ namespace
};
}
-void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event, bool passive)
+void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event)
{
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
xcb_generic_event_t *nextEvent;
@@ -861,19 +814,28 @@ void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *eve
lastEvent = (xcb_client_message_event_t *)nextEvent;
}
- handle_xdnd_position(w, lastEvent, passive);
+ handle_xdnd_position(w, lastEvent);
if (lastEvent != event)
free(lastEvent);
}
-void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event, bool)
+void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
{
DEBUG("xdndHandleStatus");
+ waiting_for_status = false;
// ignore late status messages
if (event->data.data32[0] && event->data.data32[0] != current_proxy_target)
return;
- Qt::DropAction newAction = (event->data.data32[1] & 0x1) ? toDropAction(event->data.data32[4]) : Qt::IgnoreAction;
+ const bool dropPossible = event->data.data32[1];
+ setCanDrop(dropPossible);
+
+ if (dropPossible) {
+ accepted_drop_action = toDropAction(event->data.data32[4]);
+ updateCursor(accepted_drop_action);
+ } else {
+ updateCursor(Qt::IgnoreAction);
+ }
if ((event->data.data32[1] & 2) == 0) {
QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff);
@@ -882,18 +844,9 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event, bool)
} else {
source_sameanswer = QRect();
}
- QDragManager *manager = QDragManager::self();
- manager->willDrop = (event->data.data32[1] & 0x1);
- if (manager->global_accepted_action != newAction) {
- manager->global_accepted_action = newAction;
- manager->emitActionChanged(newAction);
- }
- DEBUG() << "willDrop=" << manager->willDrop << "action=" << newAction;
- manager->updateCursor();
- waiting_for_status = false;
}
-void QXcbDrag::handleStatus(const xcb_client_message_event_t *event, bool passive)
+void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
{
if (event->window != connection()->clipboard()->owner())
return;
@@ -907,13 +860,13 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event, bool passiv
lastEvent = (xcb_client_message_event_t *)nextEvent;
}
- handle_xdnd_status(lastEvent, passive);
+ handle_xdnd_status(lastEvent);
if (lastEvent != event)
free(lastEvent);
DEBUG("xdndHandleStatus end");
}
-void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/)
+void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
{
DEBUG("xdnd leave");
if (!currentWindow || w != currentWindow.data())
@@ -931,8 +884,8 @@ void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event,
DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
}
- QDragLeaveEvent e;
- QGuiApplication::sendEvent(currentWindow.data(), &e);
+ QWindowSystemInterface::handleDrag(w,0,QPoint(),Qt::IgnoreAction);
+ updateAction(Qt::IgnoreAction);
xdnd_dragsource = 0;
xdnd_types.clear();
@@ -944,7 +897,6 @@ void QXcbDrag::send_leave()
if (!current_target)
return;
- QDragManager *manager = QDragManager::self();
xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE;
@@ -963,24 +915,18 @@ void QXcbDrag::send_leave()
w = 0;
if (w)
- handleLeave(w->window(), (const xcb_client_message_event_t *)&leave, false);
+ handleLeave(w->window(), (const xcb_client_message_event_t *)&leave);
else
xcb_send_event(xcb_connection(), false,current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
- // reset the drag manager state
- manager->willDrop = false;
- if (manager->global_accepted_action != Qt::IgnoreAction)
- manager->emitActionChanged(Qt::IgnoreAction);
- manager->global_accepted_action = Qt::IgnoreAction;
- manager->updateCursor();
current_target = 0;
current_proxy_target = 0;
source_time = XCB_CURRENT_TIME;
waiting_for_status = false;
}
-void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive)
+void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event)
{
DEBUG("xdndHandleDrop");
if (!currentWindow) {
@@ -988,16 +934,8 @@ void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bo
return; // sanity
}
- // ###
-// if (!passive && checkEmbedded(currentWindow, xe)){
-// current_embedding_widget = 0;
-// xdnd_dragsource = 0;
-// currentWindow = 0;
-// return;
-// }
const uint32_t *l = event->data.data32;
- QDragManager *manager = QDragManager::self();
DEBUG("xdnd drop");
if (l[0] != xdnd_dragsource) {
@@ -1009,50 +947,39 @@ void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bo
if (l[2] != 0)
target_time = /*X11->userTime =*/ l[2];
- if (!passive) {
- // this could be a same-application drop, just proxied due to
- // some XEMBEDding, so try to find the real QMimeData used
- // based on the timestamp for this drop.
- QMimeData *dropData = 0;
- // ###
-// int at = findXdndDropTransactionByTime(target_time);
-// if (at != -1)
-// dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
- // if we can't find it, then use the data in the drag manager
- if (!dropData)
- dropData = manager->dropData();
-
- // Drop coming from another app? Update keyboard modifiers.
-// if (!qt_xdnd_dragging) {
-// QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
-// }
-
- QDropEvent de(currentPosition, manager->possible_actions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
- QGuiApplication::sendEvent(currentWindow.data(), &de);
- if (!de.isAccepted()) {
- // Ignore a failed drag
- manager->global_accepted_action = Qt::IgnoreAction;
- } else {
- manager->global_accepted_action = de.dropAction();
- }
- xcb_client_message_event_t finished;
- finished.response_type = XCB_CLIENT_MESSAGE;
- finished.window = xdnd_dragsource;
- finished.format = 32;
- finished.type = atom(QXcbAtom::XdndFinished);
- DNDDEBUG << "xdndHandleDrop"
- << "currentWindow" << currentWindow.data()
- << (currentWindow ? xcb_window(currentWindow.data()) : 0);
- finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
- finished.data.data32[1] = de.isAccepted() ? 1 : 0; // flags
- finished.data.data32[2] = toXdndAction(manager->global_accepted_action);
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
- XCB_EVENT_MASK_NO_EVENT, (char *)&finished));
+ // this could be a same-application drop, just proxied due to
+ // some XEMBEDding, so try to find the real QMimeData used
+ // based on the timestamp for this drop.
+ Qt::DropActions supported_drop_actions(l[4]);
+ QMimeData *dropData = 0;
+ if (currentDrag()) {
+ dropData = currentDrag()->mimeData();
} else {
- QDragLeaveEvent e;
- QGuiApplication::sendEvent(currentWindow.data(), &e);
+ dropData = platformDropData();
}
+
+ if (!dropData)
+ return;
+ // ###
+ // int at = findXdndDropTransactionByTime(target_time);
+ // if (at != -1)
+ // dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
+ // if we can't find it, then use the data in the drag manager
+
+ QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(currentWindow.data(),dropData,currentPosition,supported_drop_actions);
+ setExecutedDropAction(response.acceptedAction());
+
+ xcb_client_message_event_t finished;
+ finished.response_type = XCB_CLIENT_MESSAGE;
+ finished.window = xdnd_dragsource;
+ finished.format = 32;
+ finished.type = atom(QXcbAtom::XdndFinished);
+ finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
+ finished.data.data32[1] = response.isAccepted(); // flags
+ finished.data.data32[2] = toXdndAction(response.acceptedAction());
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ XCB_EVENT_MASK_NO_EVENT, (char *)&finished));
+
xdnd_dragsource = 0;
currentWindow.clear();
waiting_for_status = false;
@@ -1062,7 +989,7 @@ void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bo
}
-void QXcbDrag::handleFinished(const xcb_client_message_event_t *event, bool)
+void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
{
DEBUG("xdndHandleFinished");
if (event->window != connection()->clipboard()->owner())
@@ -1099,8 +1026,8 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event, bool)
// current_target = 0;
// current_proxy_target = 0;
- if (t.object)
- t.object->deleteLater();
+ if (t.drag)
+ t.drag->deleteLater();
// current_target = target;
// current_proxy_target = proxy_target;
@@ -1126,7 +1053,7 @@ void QXcbDrag::timerEvent(QTimerEvent* e)
// dnd within the same process, don't delete these
continue;
}
- t.object->deleteLater();
+ t.drag->deleteLater();
transactions.removeAt(i--);
}
@@ -1138,12 +1065,9 @@ void QXcbDrag::timerEvent(QTimerEvent* e)
void QXcbDrag::cancel()
{
DEBUG("QXcbDrag::cancel");
- endDrag();
-
+ QBasicDrag::cancel();
if (current_target)
send_leave();
-
- current_target = 0;
}
@@ -1157,14 +1081,11 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
notify.property = XCB_NONE;
notify.time = event->time;
- QDragManager *manager = QDragManager::self();
- QDrag *currentObject = manager->object;
-
// which transaction do we use? (note: -2 means use current manager->object)
int at = -1;
// figure out which data the requestor is really interested in
- if (manager->object && event->time == source_time) {
+ if (currentDrag() && event->time == source_time) {
// requestor wants the current drag data
at = -2;
} else {
@@ -1188,20 +1109,18 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
// }
// }
}
+
+ QDrag *transactionDrag = 0;
if (at >= 0) {
restartDropExpiryTimer();
- // use the drag object from an XdndDrop tansaction
- manager->object = transactions.at(at).object;
- } else if (at != -2) {
- // no transaction found, we'll have to reject the request
- manager->object = 0;
+ transactionDrag = transactions.at(at).drag;
}
- if (manager->object) {
+ if (transactionDrag) {
xcb_atom_t atomFormat = event->target;
int dataFormat = 0;
QByteArray data;
- if (QXcbMime::mimeDataForAtom(connection(), event->target, manager->dragPrivate()->data,
+ if (QXcbMime::mimeDataForAtom(connection(), event->target, transactionDrag->mimeData(),
&data, &atomFormat, &dataFormat)) {
int dataSize = data.size() / (dataFormat / 8);
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, event->requestor, event->property,
@@ -1211,9 +1130,6 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
}
}
- // reset manager->object in case we modified it above
- manager->object = currentObject;
-
xcb_send_event(xcb_connection(), false, event->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&notify);
}
@@ -1268,20 +1184,17 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
}
}
-
-
-
-QDropData::QDropData(QXcbDrag *d)
+QXcbDropData::QXcbDropData(QXcbDrag *d)
: QXcbMime(),
drag(d)
{
}
-QDropData::~QDropData()
+QXcbDropData::~QXcbDropData()
{
}
-QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
+QVariant QXcbDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
{
QByteArray mime = mimetype.toLatin1();
QVariant data = /*X11->motifdnd_active
@@ -1290,17 +1203,16 @@ QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type req
return data;
}
-QVariant QDropData::xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const
+QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const
{
QByteArray result;
- QDragManager *manager = QDragManager::self();
QXcbConnection *c = drag->connection();
QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
- if (xcb_window && manager->object && xcb_window->window()->windowType() != Qt::Desktop) {
- QDragPrivate *o = manager->dragPrivate();
- if (o->data->hasFormat(QLatin1String(format)))
- result = o->data->data(QLatin1String(format));
+ if (xcb_window && drag->currentDrag() && xcb_window->window()->windowType() != Qt::Desktop) {
+ QMimeData *data = drag->currentDrag()->mimeData();
+ if (data->hasFormat(QLatin1String(format)))
+ result = data->data(QLatin1String(format));
return result;
}
@@ -1320,12 +1232,12 @@ QVariant QDropData::xdndObtainData(const QByteArray &format, QVariant::Type requ
}
-bool QDropData::hasFormat_sys(const QString &format) const
+bool QXcbDropData::hasFormat_sys(const QString &format) const
{
return formats().contains(format);
}
-QStringList QDropData::formats_sys() const
+QStringList QXcbDropData::formats_sys() const
{
QStringList formats;
// if (X11->motifdnd_active) {
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index e32e630548..710a07a5a4 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -43,6 +43,7 @@
#define QXCBDRAG_H
#include <qplatformdrag_qpa.h>
+#include <QtPlatformSupport/private/qsimpledrag_p.h>
#include <qxcbobject.h>
#include <xcb/xcb.h>
#include <qlist.h>
@@ -51,17 +52,23 @@
#include <qsharedpointer.h>
#include <qvector.h>
+#include <qpixmap.h>
+#include <qbackingstore.h>
+
+#include <QtCore/QDebug>
+
QT_BEGIN_NAMESPACE
class QMouseEvent;
class QWindow;
class QXcbConnection;
class QXcbWindow;
-class QDropData;
+class QXcbDropData;
class QXcbScreen;
class QDrag;
+class QShapedPixmapWindow;
-class QXcbDrag : public QObject, public QXcbObject, public QPlatformDrag
+class QXcbDrag : public QXcbObject, public QBasicDrag
{
public:
QXcbDrag(QXcbConnection *c);
@@ -69,35 +76,36 @@ public:
virtual QMimeData *platformDropData();
-// virtual Qt::DropAction drag(QDrag *);
- virtual void startDrag();
- virtual void cancel();
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
+ void startDrag();
+ void cancel();
+ void move(const QMouseEvent *me);
+ void drop(const QMouseEvent *me);
void endDrag();
void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
- void handlePosition(QWindow *w, const xcb_client_message_event_t *event, bool passive);
- void handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/);
- void handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive);
+ void handlePosition(QWindow *w, const xcb_client_message_event_t *event);
+ void handleLeave(QWindow *w, const xcb_client_message_event_t *event);
+ void handleDrop(QWindow *, const xcb_client_message_event_t *event);
- void handleStatus(const xcb_client_message_event_t *event, bool passive);
+ void handleStatus(const xcb_client_message_event_t *event);
void handleSelectionRequest(const xcb_selection_request_event_t *event);
- void handleFinished(const xcb_client_message_event_t *event, bool passive);
+ void handleFinished(const xcb_client_message_event_t *event);
bool dndEnable(QXcbWindow *win, bool on);
+ void updatePixmap();
+
protected:
void timerEvent(QTimerEvent* e);
private:
- friend class QDropData;
+ friend class QXcbDropData;
void init();
- void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event, bool passive);
- void handle_xdnd_status(const xcb_client_message_event_t *event, bool);
+ void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event);
+ void handle_xdnd_status(const xcb_client_message_event_t *event);
void send_leave();
Qt::DropAction toDropAction(xcb_atom_t atom) const;
@@ -106,7 +114,8 @@ private:
QWeakPointer<QWindow> currentWindow;
QPoint currentPosition;
- QDropData *dropData;
+ QXcbDropData *dropData;
+ Qt::DropAction accepted_drop_action;
QWindow *desktop_proxy;
@@ -118,7 +127,6 @@ private:
xcb_timestamp_t target_time;
xcb_timestamp_t source_time;
- Qt::DropAction last_target_accepted_action;
// rectangle in which the answer will be the same
QRect source_sameanswer;
@@ -132,7 +140,6 @@ private:
QXcbScreen *current_screen;
int heartbeat;
- bool xdnd_dragging;
QVector<xcb_atom_t> drag_types;
@@ -143,7 +150,7 @@ private:
xcb_window_t proxy_target;
QWindow *targetWindow;
// QWidget *embedding_widget;
- QDrag *object;
+ QDrag *drag;
};
QList<Transaction> transactions;
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
index 13ff8ab2a5..12979bfb68 100644
--- a/src/plugins/platforms/xcb/qxcbimage.cpp
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -201,7 +201,7 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
formatsCookie,
&error);
if (!formatsReply || error) {
- qWarning("createCursorXRender: query_pict_formats failed");
+ qWarning("qt_xcb_createCursorXRender: query_pict_formats failed");
free(formatsReply);
free(error);
return XCB_NONE;
@@ -209,7 +209,7 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply,
XCB_PICT_STANDARD_ARGB_32);
if (!fmt) {
- qWarning("createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
+ qWarning("qt_xcb_createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
free(formatsReply);
return XCB_NONE;
}
@@ -221,13 +221,13 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
XCB_IMAGE_ORDER_MSB_FIRST,
0, 0, 0);
if (!xi) {
- qWarning("createCursorXRender: xcb_image_create failed");
+ qWarning("qt_xcb_createCursorXRender: xcb_image_create failed");
free(formatsReply);
return XCB_NONE;
}
xi->data = (uint8_t *) malloc(xi->stride * h);
if (!xi->data) {
- qWarning("createCursorXRender: Failed to malloc() image data");
+ qWarning("qt_xcb_createCursorXRender: Failed to malloc() image data");
xcb_image_destroy(xi);
free(formatsReply);
return XCB_NONE;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 98f69e9e16..fe33bd7153 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -101,7 +101,9 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
m_connections << new QXcbConnection(m_nativeInterface.data());
for (int i = 0; i < parameters.size() - 1; i += 2) {
- qDebug() << parameters.at(i) << parameters.at(i+1);
+#ifdef Q_XCB_DEBUG
+ qDebug() << "QXcbIntegration: Connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
+#endif
QString display = parameters.at(i) + ':' + parameters.at(i+1);
m_connections << new QXcbConnection(m_nativeInterface.data(), display.toAscii().constData());
}
@@ -185,7 +187,7 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
#elif defined(XCB_USE_DRI2)
return new QDri2Context(context->format(), context->shareHandle());
#endif
- qWarning("Cannot create platform GL context, none of GLX, EGL, DRI2 is enabled");
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, none of GLX, EGL, or DRI2 are enabled");
return 0;
}
#endif
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index b682b87bc3..03156dc544 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -935,7 +935,7 @@ void QXcbKeyboard::setupModifiers()
xcb_get_modifier_mapping_reply_t *modMapReply =
xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
if (error) {
- qWarning("xcb keyboard: failed to get modifier mapping");
+ qWarning("QXcbKeyboard: failed to get modifier mapping");
free(error);
return;
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 406f9c24bd..f56072f9d7 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -137,7 +137,7 @@ QPlatformNativeInterface::EventFilter QXcbNativeInterface::setEventFilter(const
if (eventType == QByteArrayLiteral("xcb_generic_event_t"))
type = GenericEventFilter;
if (type == -1) {
- qWarning("%s: Attempt to set invalid event filter type '%s'.",
+ qWarning("QXcbNativeInterface: %s: Attempt to set invalid event filter type '%s'.",
Q_FUNC_INFO, eventType.constData());
return 0;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index c93b4863e1..15ffc5b8ff 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -55,6 +55,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
, m_screen(screen)
, m_number(number)
{
+#ifdef Q_XCB_DEBUG
qDebug();
qDebug("Information of screen %d:", screen->root);
qDebug(" width.........: %d", screen->width_in_pixels);
@@ -63,6 +64,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
qDebug(" white pixel...: %x", screen->white_pixel);
qDebug(" black pixel...: %x", screen->black_pixel);
qDebug();
+#endif
const quint32 mask = XCB_CW_EVENT_MASK;
const quint32 values[] = {
@@ -93,7 +95,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
atom(QXcbAtom::UTF8_STRING), 0, 1024), &error);
if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply));
+#ifdef Q_XCB_DEBUG
qDebug("Running window manager: %s", qPrintable(m_windowManagerName));
+#endif
} else if (error) {
connection->handleXcbError(error);
free(error);
diff --git a/src/plugins/platforms/xcb/qxcbsharedbuffermanager.cpp b/src/plugins/platforms/xcb/qxcbsharedbuffermanager.cpp
index f9e388b662..8bd3aea259 100644
--- a/src/plugins/platforms/xcb/qxcbsharedbuffermanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsharedbuffermanager.cpp
@@ -581,7 +581,7 @@ QXcbSharedBufferManager::Buffer *QXcbSharedBufferManager::allocateBuffer(int wid
bool ok = buffer->buffer->create(buffer->width * buffer->height * buffer->bytesPerPixel,
QSharedMemory::ReadWrite);
if (!ok) {
- qWarning("SharedBufferManager::findAvailableBuffer: Can't create new buffer (%s)",
+ qWarning("QXcbSharedBufferManager::findAvailableBuffer: Can't create new buffer (%s)",
qPrintable(buffer->buffer->errorString()));
delete buffer;
return 0;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 067cb775c8..739426a92a 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -369,6 +369,14 @@ void QXcbWindow::destroy()
if (m_syncCounter && m_screen->syncRequestSupported())
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
if (m_window) {
+ if (m_netWmUserTimeWindow) {
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+ // Some window managers, like metacity, do XSelectInput on the _NET_WM_USER_TIME_WINDOW window,
+ // without trapping BadWindow (which crashes when the user time window is destroyed).
+ connection()->sync();
+ xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
+ m_netWmUserTimeWindow = XCB_NONE;
+ }
connection()->removeWindow(m_window);
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
}
@@ -1168,10 +1176,31 @@ void QXcbWindow::propagateSizeHints()
void QXcbWindow::requestActivateWindow()
{
- if (m_mapped){
- updateNetWmUserTime(connection()->time());
+ if (!m_mapped)
+ return;
+
+ updateNetWmUserTime(connection()->time());
+
+ if (window()->isTopLevel()
+ && connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_ACTIVE_WINDOW))) {
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
+ event.data.data32[0] = 1;
+ event.data.data32[1] = connection()->time();
+ QWindow *focusWindow = QGuiApplication::focusWindow();
+ event.data.data32[2] = focusWindow ? focusWindow->winId() : XCB_NONE;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ } else {
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
}
+
connection()->sync();
}
@@ -1252,18 +1281,18 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
} else {
- qWarning() << "unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
+ qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
}
} else if (event->type == atom(QXcbAtom::XdndEnter)) {
connection()->drag()->handleEnter(window(), event);
} else if (event->type == atom(QXcbAtom::XdndPosition)) {
- connection()->drag()->handlePosition(window(), event, false);
+ connection()->drag()->handlePosition(window(), event);
} else if (event->type == atom(QXcbAtom::XdndLeave)) {
- connection()->drag()->handleLeave(window(), event, false);
+ connection()->drag()->handleLeave(window(), event);
} else if (event->type == atom(QXcbAtom::XdndDrop)) {
- connection()->drag()->handleDrop(window(), event, false);
+ connection()->drag()->handleDrop(window(), event);
} else {
- qWarning() << "unhandled client message:" << connection()->atomName(event->type);
+ qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
index 114049f911..c9f4ca69dd 100644
--- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -89,11 +89,6 @@ void QXcbWMSupport::updateNetWMAtoms()
free(reply);
} while (remaining > 0);
-
-// qDebug() << "======== updateNetWMAtoms";
-// for (int i = 0; i < net_wm_atoms.size(); ++i)
-// qDebug() << atomName(net_wm_atoms.at(i));
-// qDebug() << "======== updateNetWMAtoms";
}
// update the virtual roots array
@@ -130,10 +125,12 @@ void QXcbWMSupport::updateVirtualRoots()
free(reply);
} while (remaining > 0);
+#ifdef Q_XCB_DEBUG
qDebug() << "======== updateVirtualRoots";
for (int i = 0; i < net_virtual_roots.size(); ++i)
qDebug() << connection()->atomName(net_virtual_roots.at(i));
qDebug() << "======== updateVirtualRoots";
+#endif
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 7bad2b4dad..d220766be0 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -94,7 +94,7 @@ contains(DEFINES, XCB_USE_DRI2) {
}
}
-LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes
+LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shape
DEFINES += $$QMAKE_DEFINES_XCB
LIBS += $$QMAKE_LIBS_XCB
diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp
index 1c66c1888f..4e3586f646 100644
--- a/src/printsupport/dialogs/qabstractprintdialog.cpp
+++ b/src/printsupport/dialogs/qabstractprintdialog.cpp
@@ -386,8 +386,8 @@ void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter)
\table
\row
- \o \inlineimage plastique-printdialog.png
- \o \inlineimage plastique-printdialog-properties.png
+ \li \inlineimage plastique-printdialog.png
+ \li \inlineimage plastique-printdialog-properties.png
\endtable
The printer dialog (shown above in Plastique style) enables access to common
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index d50424609a..c7b450786d 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -647,13 +647,13 @@ void QPrintPreviewDialogPrivate::_q_zoomFactorChanged()
straightforward:
\list 1
- \o Create the QPrintPreviewDialog.
+ \li Create the QPrintPreviewDialog.
You can construct a QPrintPreviewDialog with an existing QPrinter
object, or you can have QPrintPreviewDialog create one for you,
which will be the system default printer.
- \o Connect the paintRequested() signal to a slot.
+ \li Connect the paintRequested() signal to a slot.
When the dialog needs to generate a set of preview pages, the
paintRequested() signal will be emitted. You can use the exact
@@ -663,7 +663,7 @@ void QPrintPreviewDialogPrivate::_q_zoomFactorChanged()
signal, where you draw onto the QPrinter object that is passed
into the slot.
- \o Call exec().
+ \li Call exec().
Call QPrintPreviewDialog::exec() to show the preview dialog.
\endlist
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index e0373d99e8..447c535420 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -264,14 +264,14 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
The most important parameters are:
\list
- \i setOrientation() tells QPrinter which page orientation to use.
- \i setPaperSize() tells QPrinter what paper size to expect from the
+ \li setOrientation() tells QPrinter which page orientation to use.
+ \li setPaperSize() tells QPrinter what paper size to expect from the
printer.
- \i setResolution() tells QPrinter what resolution you wish the
+ \li setResolution() tells QPrinter what resolution you wish the
printer to provide, in dots per inch (DPI).
- \i setFullPage() tells QPrinter whether you want to deal with the
+ \li setFullPage() tells QPrinter whether you want to deal with the
full page or just with the part the printer can draw on.
- \i setCopyCount() tells QPrinter how many copies of the document
+ \li setCopyCount() tells QPrinter how many copies of the document
it should print.
\endlist
diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp
index ce2c6955a0..16aea238b1 100644
--- a/src/printsupport/widgets/qprintpreviewwidget.cpp
+++ b/src/printsupport/widgets/qprintpreviewwidget.cpp
@@ -467,13 +467,13 @@ void QPrintPreviewWidgetPrivate::setZoomFactor(qreal _zoomFactor)
Using QPrintPreviewWidget is straightforward:
\list 1
- \o Create the QPrintPreviewWidget
+ \li Create the QPrintPreviewWidget
Construct the QPrintPreviewWidget either by passing in an
existing QPrinter object, or have QPrintPreviewWidget create a
default constructed QPrinter object for you.
- \o Connect the paintRequested() signal to a slot.
+ \li Connect the paintRequested() signal to a slot.
When the widget needs to generate a set of preview pages, a
paintRequested() signal will be emitted from the widget. Connect a
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 7b6a2b8c12..d4633cea57 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -650,16 +650,16 @@ QStringList QSqlDatabase::connectionNames()
The currently available driver types are:
\table
- \header \i Driver Type \i Description
- \row \i QDB2 \i IBM DB2
- \row \i QIBASE \i Borland InterBase Driver
- \row \i QMYSQL \i MySQL Driver
- \row \i QOCI \i Oracle Call Interface Driver
- \row \i QODBC \i ODBC Driver (includes Microsoft SQL Server)
- \row \i QPSQL \i PostgreSQL Driver
- \row \i QSQLITE \i SQLite version 3 or above
- \row \i QSQLITE2 \i SQLite version 2
- \row \i QTDS \i Sybase Adaptive Server
+ \header \li Driver Type \li Description
+ \row \li QDB2 \li IBM DB2
+ \row \li QIBASE \li Borland InterBase Driver
+ \row \li QMYSQL \li MySQL Driver
+ \row \li QOCI \li Oracle Call Interface Driver
+ \row \li QODBC \li ODBC Driver (includes Microsoft SQL Server)
+ \row \li QPSQL \li PostgreSQL Driver
+ \row \li QSQLITE \li SQLite version 3 or above
+ \row \li QSQLITE2 \li SQLite version 2
+ \row \li QTDS \li Sybase Adaptive Server
\endtable
Additional third party drivers, including your own custom
@@ -1202,77 +1202,77 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const
database client used:
\table
- \header \i ODBC \i MySQL \i PostgreSQL
+ \header \li ODBC \li MySQL \li PostgreSQL
\row
- \i
+ \li
\list
- \i SQL_ATTR_ACCESS_MODE
- \i SQL_ATTR_LOGIN_TIMEOUT
- \i SQL_ATTR_CONNECTION_TIMEOUT
- \i SQL_ATTR_CURRENT_CATALOG
- \i SQL_ATTR_METADATA_ID
- \i SQL_ATTR_PACKET_SIZE
- \i SQL_ATTR_TRACEFILE
- \i SQL_ATTR_TRACE
- \i SQL_ATTR_CONNECTION_POOLING
- \i SQL_ATTR_ODBC_VERSION
+ \li SQL_ATTR_ACCESS_MODE
+ \li SQL_ATTR_LOGIN_TIMEOUT
+ \li SQL_ATTR_CONNECTION_TIMEOUT
+ \li SQL_ATTR_CURRENT_CATALOG
+ \li SQL_ATTR_METADATA_ID
+ \li SQL_ATTR_PACKET_SIZE
+ \li SQL_ATTR_TRACEFILE
+ \li SQL_ATTR_TRACE
+ \li SQL_ATTR_CONNECTION_POOLING
+ \li SQL_ATTR_ODBC_VERSION
\endlist
- \i
+ \li
\list
- \i CLIENT_COMPRESS
- \i CLIENT_FOUND_ROWS
- \i CLIENT_IGNORE_SPACE
- \i CLIENT_SSL
- \i CLIENT_ODBC
- \i CLIENT_NO_SCHEMA
- \i CLIENT_INTERACTIVE
- \i UNIX_SOCKET
- \i MYSQL_OPT_RECONNECT
+ \li CLIENT_COMPRESS
+ \li CLIENT_FOUND_ROWS
+ \li CLIENT_IGNORE_SPACE
+ \li CLIENT_SSL
+ \li CLIENT_ODBC
+ \li CLIENT_NO_SCHEMA
+ \li CLIENT_INTERACTIVE
+ \li UNIX_SOCKET
+ \li MYSQL_OPT_RECONNECT
\endlist
- \i
+ \li
\list
- \i connect_timeout
- \i options
- \i tty
- \i requiressl
- \i service
+ \li connect_timeout
+ \li options
+ \li tty
+ \li requiressl
+ \li service
\endlist
- \header \i DB2 \i OCI \i TDS
+ \header \li DB2 \li OCI \li TDS
\row
- \i
+ \li
\list
- \i SQL_ATTR_ACCESS_MODE
- \i SQL_ATTR_LOGIN_TIMEOUT
+ \li SQL_ATTR_ACCESS_MODE
+ \li SQL_ATTR_LOGIN_TIMEOUT
\endlist
- \i
+ \li
\list
- \i OCI_ATTR_PREFETCH_ROWS
- \i OCI_ATTR_PREFETCH_MEMORY
+ \li OCI_ATTR_PREFETCH_ROWS
+ \li OCI_ATTR_PREFETCH_MEMORY
\endlist
- \i
+ \li
\e none
- \header \i SQLite \i Interbase
+ \header \li SQLite \li Interbase
\row
- \i
+ \li
\list
- \i QSQLITE_BUSY_TIMEOUT
- \i QSQLITE_OPEN_READONLY
- \i QSQLITE_ENABLE_SHARED_CACHE
+ \li QSQLITE_BUSY_TIMEOUT
+ \li QSQLITE_OPEN_READONLY
+ \li QSQLITE_ENABLE_SHARED_CACHE
\endlist
- \i
+ \li
\list
- \i ISC_DPB_LC_CTYPE
- \i ISC_DPB_SQL_ROLE_NAME
+ \li ISC_DPB_LC_CTYPE
+ \li ISC_DPB_SQL_ROLE_NAME
\endlist
\endtable
@@ -1354,47 +1354,47 @@ bool QSqlDatabase::isDriverAvailable(const QString& name)
and their constructor arguments:
\table
- \header \i Driver \i Class name \i Constructor arguments \i File to include
+ \header \li Driver \li Class name \li Constructor arguments \li File to include
\row
- \i QPSQL
- \i QPSQLDriver
- \i PGconn *connection
- \i \c qsql_psql.cpp
+ \li QPSQL
+ \li QPSQLDriver
+ \li PGconn *connection
+ \li \c qsql_psql.cpp
\row
- \i QMYSQL
- \i QMYSQLDriver
- \i MYSQL *connection
- \i \c qsql_mysql.cpp
+ \li QMYSQL
+ \li QMYSQLDriver
+ \li MYSQL *connection
+ \li \c qsql_mysql.cpp
\row
- \i QOCI
- \i QOCIDriver
- \i OCIEnv *environment, OCISvcCtx *serviceContext
- \i \c qsql_oci.cpp
+ \li QOCI
+ \li QOCIDriver
+ \li OCIEnv *environment, OCISvcCtx *serviceContext
+ \li \c qsql_oci.cpp
\row
- \i QODBC
- \i QODBCDriver
- \i SQLHANDLE environment, SQLHANDLE connection
- \i \c qsql_odbc.cpp
+ \li QODBC
+ \li QODBCDriver
+ \li SQLHANDLE environment, SQLHANDLE connection
+ \li \c qsql_odbc.cpp
\row
- \i QDB2
- \i QDB2
- \i SQLHANDLE environment, SQLHANDLE connection
- \i \c qsql_db2.cpp
+ \li QDB2
+ \li QDB2
+ \li SQLHANDLE environment, SQLHANDLE connection
+ \li \c qsql_db2.cpp
\row
- \i QTDS
- \i QTDSDriver
- \i LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString &hostName
- \i \c qsql_tds.cpp
+ \li QTDS
+ \li QTDSDriver
+ \li LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString &hostName
+ \li \c qsql_tds.cpp
\row
- \i QSQLITE
- \i QSQLiteDriver
- \i sqlite *connection
- \i \c qsql_sqlite.cpp
+ \li QSQLITE
+ \li QSQLiteDriver
+ \li sqlite *connection
+ \li \c qsql_sqlite.cpp
\row
- \i QIBASE
- \i QIBaseDriver
- \i isc_db_handle connection
- \i \c qsql_ibase.cpp
+ \li QIBASE
+ \li QIBaseDriver
+ \li isc_db_handle connection
+ \li \c qsql_ibase.cpp
\endtable
The host name (or service name) is needed when constructing the
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 861cd4ad0f..7e6a7f7386 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -569,22 +569,22 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
\list
- \i If \a field is character data, the value is returned enclosed
+ \li If \a field is character data, the value is returned enclosed
in single quotation marks, which is appropriate for many SQL
databases. Any embedded single-quote characters are escaped
(replaced with two single-quote characters). If \a trimStrings is
true (the default is false), all trailing whitespace is trimmed
from the field.
- \i If \a field is date/time data, the value is formatted in ISO
+ \li If \a field is date/time data, the value is formatted in ISO
format and enclosed in single quotation marks. If the date/time
data is invalid, "NULL" is returned.
- \i If \a field is \link QByteArray bytearray\endlink data, and the
+ \li If \a field is \link QByteArray bytearray\endlink data, and the
driver can edit binary fields, the value is formatted as a
hexadecimal string.
- \i For any other field type, toString() is called on its value
+ \li For any other field type, toString() is called on its value
and the result of this is returned.
\endlist
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index 3e6712b27e..e21a8f4956 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -130,11 +130,11 @@ QSqlQueryPrivate::~QSqlQueryPrivate()
Navigating records is performed with the following functions:
\list
- \o next()
- \o previous()
- \o first()
- \o last()
- \o seek()
+ \li next()
+ \li previous()
+ \li first()
+ \li last()
+ \li seek()
\endlist
These functions allow the programmer to move forward, backward
@@ -188,23 +188,23 @@ QSqlQueryPrivate::~QSqlQueryPrivate()
different binding approaches, as well as one example of binding
values to a stored procedure.
- \bold{Named binding using named placeholders:}
+ \b{Named binding using named placeholders:}
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 9
- \bold{Positional binding using named placeholders:}
+ \b{Positional binding using named placeholders:}
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 10
- \bold{Binding values using positional placeholders (version 1):}
+ \b{Binding values using positional placeholders (version 1):}
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 11
- \bold{Binding values using positional placeholders (version 2):}
+ \b{Binding values using positional placeholders (version 2):}
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 12
- \bold{Binding values to a stored procedure:}
+ \b{Binding values to a stored procedure:}
This code calls a stored procedure called \c AsciiToInt(), passing
it a character through its in parameter, and taking its result in
@@ -460,10 +460,10 @@ const QSqlResult* QSqlQuery::result() const
\list
- \o If \a index is negative, the result is positioned before the
+ \li If \a index is negative, the result is positioned before the
first record and false is returned.
- \o Otherwise, an attempt is made to move to the record at position
+ \li Otherwise, an attempt is made to move to the record at position
\a index. If the record at position \a index could not be retrieved,
the result is positioned after the last record and false is
returned. If the record is successfully retrieved, true is returned.
@@ -474,18 +474,18 @@ const QSqlResult* QSqlQuery::result() const
\list
- \o If the result is currently positioned before the first record or
+ \li If the result is currently positioned before the first record or
on the first record, and \a index is negative, there is no change,
and false is returned.
- \o If the result is currently located after the last record, and \a
+ \li If the result is currently located after the last record, and \a
index is positive, there is no change, and false is returned.
- \o If the result is currently located somewhere in the middle, and
+ \li If the result is currently located somewhere in the middle, and
the relative offset \a index moves the result below zero, the result
is positioned before the first record and false is returned.
- \o Otherwise, an attempt is made to move to the record \a index
+ \li Otherwise, an attempt is made to move to the record \a index
records ahead of the current record (or \a index records behind the
current record if \a index is negative). If the record at offset \a
index could not be retrieved, the result is positioned after the
@@ -571,14 +571,14 @@ bool QSqlQuery::seek(int index, bool relative)
\list
- \o If the result is currently located before the first record,
+ \li If the result is currently located before the first record,
e.g. immediately after a query is executed, an attempt is made to
retrieve the first record.
- \o If the result is currently located after the last record, there
+ \li If the result is currently located after the last record, there
is no change and false is returned.
- \o If the result is located somewhere in the middle, an attempt is
+ \li If the result is located somewhere in the middle, an attempt is
made to retrieve the next record.
\endlist
@@ -621,13 +621,13 @@ bool QSqlQuery::next()
\list
- \o If the result is currently located before the first record, there
+ \li If the result is currently located before the first record, there
is no change and false is returned.
- \o If the result is currently located after the last record, an
+ \li If the result is currently located after the last record, an
attempt is made to retrieve the last record.
- \o If the result is somewhere in the middle, an attempt is made to
+ \li If the result is somewhere in the middle, an attempt is made to
retrieve the previous record.
\endlist
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 8dd18ca1d0..3a521deea2 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -331,8 +331,8 @@ void QSqlRelationalTableModelPrivate::clearCache()
columns to be set as foreign keys into other database tables.
\table
- \row \o \inlineimage noforeignkeys.png
- \o \inlineimage foreignkeys.png
+ \row \li \inlineimage noforeignkeys.png
+ \li \inlineimage foreignkeys.png
\endtable
The screenshot on the left shows a plain QSqlTableModel in a
@@ -375,14 +375,14 @@ void QSqlRelationalTableModelPrivate::clearCache()
Notes:
\list
- \o The table must have a primary key declared.
- \o The table's primary key may not contain a relation to
+ \li The table must have a primary key declared.
+ \li The table's primary key may not contain a relation to
another table.
- \o If a relational table contains keys that refer to non-existent
+ \li If a relational table contains keys that refer to non-existent
rows in the referenced table, the rows containing the invalid
keys will not be exposed through the model. The user or the
database is responsible for keeping referential integrity.
- \o If a relation's display column name is also used as a column
+ \li If a relation's display column name is also used as a column
name in the main table, or if it is used as display column
name in more than one relation it will be aliased. The alias is
is the relation's table name and display column name joined
@@ -393,7 +393,7 @@ void QSqlRelationalTableModelPrivate::clearCache()
QSqlRelation, so QSqlRelation::displayColumn() will return the
original display column name, but QSqlRecord::fieldName() will
return aliases.
- \o When using setData() the role should always be Qt::EditRole,
+ \li When using setData() the role should always be Qt::EditRole,
and when using data() the role should always be Qt::DisplayRole.
\endlist
diff --git a/src/src.pro b/src/src.pro
index 6e1517fb07..941064eb59 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -90,8 +90,8 @@ for(subname, SRC_SUBDIRS) {
subdir = $$replace(subdir, $$reg_src, $$QT_BUILD_TREE)
subdir = $$replace(subdir, /, $$QMAKE_DIR_SEP)
subdir = $$replace(subdir, \\\\, $$QMAKE_DIR_SEP)
- SUB_TEMPLATE = $$fromfile($$subpro, TEMPLATE)
- !isEqual(subname, src_tools_bootstrap):if(isEqual(SUB_TEMPLATE, lib) | isEqual(SUB_TEMPLATE, subdirs)):!separate_debug_info {
+ include($$subpro, SUB)
+ !isEqual(subname, src_tools_bootstrap):if(isEqual(SUB.TEMPLATE, lib) | isEqual(SUB.TEMPLATE, subdirs)):!separate_debug_info {
#debug
debug-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_DEBUG_TARGETS
debug-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) debug)
diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc
index 5fa3667d6b..dddaed74f6 100644
--- a/src/testlib/qsignalspy.qdoc
+++ b/src/testlib/qsignalspy.qdoc
@@ -48,7 +48,7 @@
\snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 1
- \bold {Note:} Non-standard data types need to be registered, using
+ \b {Note:} Non-standard data types need to be registered, using
the qRegisterMetaType() function, before you can create a
QSignalSpy. For example:
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index a4f1a39bbd..5aac97cfab 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
true, execution continues. If not, a failure is recorded in the test log
and the test won't be executed further.
- \bold {Note:} This macro can only be used in a test function that is invoked
+ \b {Note:} This macro can only be used in a test function that is invoked
by the test framework.
Example:
@@ -246,7 +246,7 @@ QT_BEGIN_NAMESPACE
\c aString and \c expected are variables on the stack that are initialized with
the current test data.
- \bold {Note:} This macro can only be used in a test function that is invoked
+ \b {Note:} This macro can only be used in a test function that is invoked
by the test framework. The test function must have a _data function.
*/
@@ -266,7 +266,7 @@ QT_BEGIN_NAMESPACE
This macro can be used to force a test failure. The test stops
executing and the failure \a message is appended to the test log.
- \bold {Note:} This macro can only be used in a test function that is invoked
+ \b {Note:} This macro can only be used in a test function that is invoked
by the test framework.
Example:
@@ -316,7 +316,7 @@ QT_BEGIN_NAMESPACE
If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
skip all test and _data functions.
- \bold {Note:} This macro can only be used in a test function or _data
+ \b {Note:} This macro can only be used in a test function or _data
function that is invoked by the test framework.
Example:
@@ -343,7 +343,7 @@ QT_BEGIN_NAMESPACE
\a mode is a \l QTest::TestFailMode and sets whether the test should
continue to execute or not.
- \bold {Note:} This macro can only be used in a test function that is invoked
+ \b {Note:} This macro can only be used in a test function that is invoked
by the test framework.
Example 1:
@@ -379,11 +379,11 @@ QT_BEGIN_NAMESPACE
resolves to an existing file or directory:
\list
- \o \a filename relative to QCoreApplication::applicationDirPath()
+ \li \a filename relative to QCoreApplication::applicationDirPath()
(only if a QCoreApplication or QApplication object has been created).
- \o \a filename relative to the test's standard install directory
+ \li \a filename relative to the test's standard install directory
(QLibraryInfo::TestsPath with the lowercased testcase name appended).
- \o \a filename relative to the directory containing the source file from which
+ \li \a filename relative to the directory containing the source file from which
QFINDTESTDATA is invoked.
\endlist
@@ -396,16 +396,16 @@ QT_BEGIN_NAMESPACE
The testdata file will be resolved as the first existing file from:
\list
- \o \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
- \o \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
- \o \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
+ \li \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
+ \li \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
+ \li \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
\endlist
This allows the test to find its testdata regardless of whether the
test has been installed, and regardless of whether the test's build tree
is equal to the test's source tree.
- \bold {Note:} reliable detection of testdata from the source directory requires
+ \b {Note:} reliable detection of testdata from the source directory requires
either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
point to the working directory from which the compiler is invoked, or only
absolute paths to the source files are passed to the compiler. Otherwise, the
@@ -427,7 +427,7 @@ QT_BEGIN_NAMESPACE
Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
\c QT_GUI_LIB will be defined automatically.
- \bold {Note:} On platforms that have keypad navigation enabled by default,
+ \b {Note:} On platforms that have keypad navigation enabled by default,
this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
to simplify the usage of key events when writing autotests. If you wish to write a
test case that uses keypad navigation, you should enable it either in the
@@ -597,7 +597,7 @@ QT_BEGIN_NAMESPACE
Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
- \bold {Note:} At some point you should release the key using \l keyRelease().
+ \b {Note:} At some point you should release the key using \l keyRelease().
\sa QTest::keyRelease(), QTest::keyClick()
*/
@@ -610,7 +610,7 @@ QT_BEGIN_NAMESPACE
If \a delay is larger than 0, the test will wait for \a delay milliseconds
before pressing the key.
- \bold {Note:} At some point you should release the key using \l keyRelease().
+ \b {Note:} At some point you should release the key using \l keyRelease().
\sa QTest::keyRelease(), QTest::keyClick()
*/
@@ -714,7 +714,7 @@ QT_BEGIN_NAMESPACE
You can add specializations of this function to your test to enable
verbose output.
- \bold {Note:} The caller of toString() must delete the returned data
+ \b {Note:} The caller of toString() must delete the returned data
using \c{delete[]}. Your implementation should return a string
created with \c{new[]} or qstrdup().
@@ -1191,11 +1191,13 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" *** If no output file is specified, stdout is assumed.\n"
" *** If no output format is specified, -txt is assumed.\n"
"\n"
- " Detail options:\n"
- " -silent : Only output failures and fatal errors in plain text output\n"
- " -v1 : Print enter messages for each testfunction\n"
- " -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n"
- " -vs : Print every signal emitted\n"
+ " Test log detail options:\n"
+ " -silent : Log failures and fatal errors only\n"
+ " -v1 : Log the start of each testfunction\n"
+ " -v2 : Log each QVERIFY/QCOMPARE/QTEST (implies -v1)\n"
+ " -vs : Log every signal emission and resulting slot invocations\n"
+ "\n"
+ " *** The -silent and -v1 options only affect plain text output.\n"
"\n"
" Testing options:\n"
" -functions : Returns a list of current testfunctions\n"
@@ -2126,7 +2128,7 @@ void QTest::qWarn(const char *message, const char *file, int line)
test log. If the test finished and the \a message was not outputted,
a test failure is appended to the test log.
- \bold {Note:} Invoking this function will only ignore one message.
+ \b {Note:} Invoking this function will only ignore one message.
If the message you want to ignore is outputted twice, you have to
call ignoreMessage() twice, too.
@@ -2293,7 +2295,7 @@ void QTest::addColumnInternal(int id, const char *name)
Example:
\snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 20
- \bold {Note:} This macro can only be used in a test's data function
+ \b {Note:} This macro can only be used in a test's data function
that is invoked by the test framework.
See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
@@ -2326,7 +2328,7 @@ QTestData &QTest::newRow(const char *dataTag)
To add custom types to the testdata, the type must be registered with
QMetaType via \l Q_DECLARE_METATYPE().
- \bold {Note:} This macro can only be used in a test's data function
+ \b {Note:} This macro can only be used in a test's data function
that is invoked by the test framework.
See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
@@ -2372,7 +2374,7 @@ bool QTest::currentTestFailed()
\a ms must be greater than 0.
- \bold {Note:} The qSleep() function calls either \c nanosleep() on
+ \b {Note:} The qSleep() function calls either \c nanosleep() on
unix or \c Sleep() on windows, so the accuracy of time spent in
qSleep() depends on the operating system.
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index cf10163539..082339cac9 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -32,8 +32,8 @@ for(subname, TOOLS_SUBDIRS) {
subdir = $$replace(subdir, $$reg_src, $$QT_BUILD_TREE)
subdir = $$replace(subdir, /, $$QMAKE_DIR_SEP)
subdir = $$replace(subdir, \\\\, $$QMAKE_DIR_SEP)
- SUB_TEMPLATE = $$fromfile($$subpro, TEMPLATE)
- !isEqual(subname, src_tools_bootstrap):if(isEqual(SUB_TEMPLATE, lib) | isEqual(SUB_TEMPLATE, subdirs)):!separate_debug_info {
+ include($$subpro, SUB)
+ !isEqual(subname, src_tools_bootstrap):if(isEqual(SUB.TEMPLATE, lib) | isEqual(SUB.TEMPLATE, subdirs)):!separate_debug_info {
#debug
debug-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_DEBUG_TARGETS
debug-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) debug)
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 5ffb5466d6..4170df4799 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -166,7 +166,7 @@ QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
\section1 Modal Dialogs
- A \bold{modal} dialog is a dialog that blocks input to other
+ A \b{modal} dialog is a dialog that blocks input to other
visible windows in the same application. Dialogs that are used to
request a file name from the user or that are used to set
application preferences are usually modal. Dialogs can be
@@ -200,7 +200,7 @@ QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
\section1 Modeless Dialogs
- A \bold{modeless} dialog is a dialog that operates
+ A \b{modeless} dialog is a dialog that operates
independently of other windows in the same application. Find and
replace dialogs in word-processors are often modeless to allow the
user to interact with both the application's main window and with
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 84fdef6702..3908daec9c 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1096,7 +1096,7 @@ QStringList qt_make_filter_list(const QString &filter)
Sets the filter used in the file dialog to the given \a filter.
If \a filter contains a pair of parentheses containing one or more
- of \bold{anything*something}, separated by spaces, then only the
+ of \b{anything*something}, separated by spaces, then only the
text contained in the parentheses is used as the filter. This means
that these calls are all equivalent:
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 0211b2512c..5446eca383 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -130,12 +130,12 @@ QT_BEGIN_NAMESPACE
\fn bool QFileSystemModel::rmdir(const QModelIndex &index) const
Removes the directory corresponding to the model item \a index in the
- file system model and \bold{deletes the corresponding directory from the
+ file system model and \b{deletes the corresponding directory from the
file system}, returning true if successful. If the directory cannot be
removed, false is returned.
\warning This function deletes directories from the file system; it does
- \bold{not} move them to a location where they can be recovered.
+ \b{not} move them to a location where they can be recovered.
\sa remove()
*/
@@ -185,11 +185,11 @@ QT_BEGIN_NAMESPACE
/*!
\fn bool QFileSystemModel::remove(const QModelIndex &index) const
- Removes the model item \a index from the file system model and \bold{deletes the
+ Removes the model item \a index from the file system model and \b{deletes the
corresponding file from the file system}, returning true if successful. If the
item cannot be removed, false is returned.
- \warning This function deletes files from the file system; it does \bold{not}
+ \warning This function deletes files from the file system; it does \b{not}
move them to a location where they can be recovered.
\sa rmdir()
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 9cf41003f5..737d6bb467 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -1031,10 +1031,10 @@ QString QInputDialog::cancelButtonText() const
in \a member. These are:
\list
- \o textValueSelected() if \a member has a QString for its first argument.
- \o intValueSelected() if \a member has an int for its first argument.
- \o doubleValueSelected() if \a member has a double for its first argument.
- \o accepted() if \a member has NO arguments.
+ \li textValueSelected() if \a member has a QString for its first argument.
+ \li intValueSelected() if \a member has an int for its first argument.
+ \li doubleValueSelected() if \a member has a double for its first argument.
+ \li accepted() if \a member has NO arguments.
\endlist
The signal will be disconnected from the slot when the dialog is closed.
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index a737584e3f..3909125fe7 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -577,21 +577,21 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
\table
\row
- \o \img qmessagebox-quest.png
- \o \l Question
- \o For asking a question during normal operations.
+ \li \img qmessagebox-quest.png
+ \li \l Question
+ \li For asking a question during normal operations.
\row
- \o \img qmessagebox-info.png
- \o \l Information
- \o For reporting information about normal operations.
+ \li \img qmessagebox-info.png
+ \li \l Information
+ \li For reporting information about normal operations.
\row
- \o \img qmessagebox-warn.png
- \o \l Warning
- \o For reporting non-critical errors.
+ \li \img qmessagebox-warn.png
+ \li \l Warning
+ \li For reporting non-critical errors.
\row
- \o \img qmessagebox-crit.png
- \o \l Critical
- \o For reporting critical errors.
+ \li \img qmessagebox-crit.png
+ \li \l Critical
+ \li For reporting critical errors.
\endtable
\l{QMessageBox::Icon}{Predefined icons} are not defined by QMessageBox, but
@@ -663,13 +663,13 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
\list 1
- \o If there is only one button, it is the button activated when
+ \li If there is only one button, it is the button activated when
\key Esc is pressed.
- \o If there is a \l Cancel button, it is the button activated when
+ \li If there is a \l Cancel button, it is the button activated when
\key Esc is pressed.
- \o If there is exactly one button having either
+ \li If there is exactly one button having either
\l{QMessageBox::RejectRole} {the Reject role} or the
\l{QMessageBox::NoRole} {the No role}, it is the button
activated when \key Esc is pressed.
@@ -927,9 +927,9 @@ QAbstractButton *QMessageBox::button(StandardButton which) const
escape button as follows:
\list 1
- \o If there is only one button, it is made the escape button.
- \o If there is a \l Cancel button, it is made the escape button.
- \o On Mac OS X only, if there is exactly one button with the role
+ \li If there is only one button, it is made the escape button.
+ \li If there is a \l Cancel button, it is made the escape button.
+ \li On Mac OS X only, if there is exactly one button with the role
QMessageBox::RejectRole, it is made the escape button.
\endlist
@@ -1142,11 +1142,11 @@ void QMessageBox::setText(const QString &text)
values:
\list
- \o QMessageBox::NoIcon
- \o QMessageBox::Question
- \o QMessageBox::Information
- \o QMessageBox::Warning
- \o QMessageBox::Critical
+ \li QMessageBox::NoIcon
+ \li QMessageBox::Question
+ \li QMessageBox::Information
+ \li QMessageBox::Warning
+ \li QMessageBox::Critical
\endlist
The default is QMessageBox::NoIcon.
@@ -1649,12 +1649,12 @@ QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString
about() looks for a suitable icon in four locations:
\list 1
- \o It prefers \link QWidget::windowIcon() parent->icon() \endlink
+ \li It prefers \link QWidget::windowIcon() parent->icon() \endlink
if that exists.
- \o If not, it tries the top-level widget containing \a parent.
- \o If that fails, it tries the \link
+ \li If not, it tries the top-level widget containing \a parent.
+ \li If that fails, it tries the \link
QApplication::activeWindow() active window. \endlink
- \o As a last resort it uses the Information icon.
+ \li As a last resort it uses the Information icon.
\endlist
The about box has a single button labelled "OK". On Mac OS X, the
@@ -1929,26 +1929,26 @@ void QMessageBoxPrivate::retranslateStrings()
The \a icon must be one of the following:
\list
- \o QMessageBox::NoIcon
- \o QMessageBox::Question
- \o QMessageBox::Information
- \o QMessageBox::Warning
- \o QMessageBox::Critical
+ \li QMessageBox::NoIcon
+ \li QMessageBox::Question
+ \li QMessageBox::Information
+ \li QMessageBox::Warning
+ \li QMessageBox::Critical
\endlist
Each button, \a button0, \a button1 and \a button2, can have one
of the following values:
\list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
+ \li QMessageBox::NoButton
+ \li QMessageBox::Ok
+ \li QMessageBox::Cancel
+ \li QMessageBox::Yes
+ \li QMessageBox::No
+ \li QMessageBox::Abort
+ \li QMessageBox::Retry
+ \li QMessageBox::Ignore
+ \li QMessageBox::YesAll
+ \li QMessageBox::NoAll
\endlist
Use QMessageBox::NoButton for the later parameters to have fewer
@@ -1994,16 +1994,16 @@ QMessageBox::QMessageBox(const QString &title, const QString &text, Icon icon,
of the following values:
\list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
+ \li QMessageBox::NoButton
+ \li QMessageBox::Ok
+ \li QMessageBox::Cancel
+ \li QMessageBox::Yes
+ \li QMessageBox::No
+ \li QMessageBox::Abort
+ \li QMessageBox::Retry
+ \li QMessageBox::Ignore
+ \li QMessageBox::YesAll
+ \li QMessageBox::NoAll
\endlist
If you don't want all three buttons, set the last button, or last
@@ -2080,16 +2080,16 @@ int QMessageBox::information(QWidget *parent, const QString &title, const QStrin
following values:
\list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
+ \li QMessageBox::NoButton
+ \li QMessageBox::Ok
+ \li QMessageBox::Cancel
+ \li QMessageBox::Yes
+ \li QMessageBox::No
+ \li QMessageBox::Abort
+ \li QMessageBox::Retry
+ \li QMessageBox::Ignore
+ \li QMessageBox::YesAll
+ \li QMessageBox::NoAll
\endlist
If you don't want all three buttons, set the last button, or last
@@ -2166,16 +2166,16 @@ int QMessageBox::question(QWidget *parent, const QString &title, const QString&
one of the following values:
\list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
+ \li QMessageBox::NoButton
+ \li QMessageBox::Ok
+ \li QMessageBox::Cancel
+ \li QMessageBox::Yes
+ \li QMessageBox::No
+ \li QMessageBox::Abort
+ \li QMessageBox::Retry
+ \li QMessageBox::Ignore
+ \li QMessageBox::YesAll
+ \li QMessageBox::NoAll
\endlist
If you don't want all three buttons, set the last button, or last
@@ -2251,16 +2251,16 @@ int QMessageBox::warning(QWidget *parent, const QString &title, const QString& t
one of the following values:
\list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
+ \li QMessageBox::NoButton
+ \li QMessageBox::Ok
+ \li QMessageBox::Cancel
+ \li QMessageBox::Yes
+ \li QMessageBox::No
+ \li QMessageBox::Abort
+ \li QMessageBox::Retry
+ \li QMessageBox::Ignore
+ \li QMessageBox::YesAll
+ \li QMessageBox::NoAll
\endlist
If you don't want all three buttons, set the last button, or last
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index f39a7b63ec..350fb57e20 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -281,10 +281,10 @@ void QProgressDialogPrivate::_q_disconnectOnClose()
Default settings:
\list
- \i The label text is empty.
- \i The cancel button text is (translated) "Cancel".
- \i minimum is 0;
- \i maximum is 100
+ \li The label text is empty.
+ \li The cancel button text is (translated) "Cancel".
+ \li minimum is 0;
+ \li maximum is 100
\endlist
The \a parent argument is dialog's parent widget. The widget flags, \a f, are
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 324831ea52..8a75353c86 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -1826,28 +1826,28 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)
QWizard supports four wizard looks:
\list
- \o ClassicStyle
- \o ModernStyle
- \o MacStyle
- \o AeroStyle
+ \li ClassicStyle
+ \li ModernStyle
+ \li MacStyle
+ \li AeroStyle
\endlist
You can explicitly set the look to use using setWizardStyle()
(e.g., if you want the same look on all platforms).
\table
- \header \o ClassicStyle
- \o ModernStyle
- \o MacStyle
- \o AeroStyle
- \row \o \inlineimage qtwizard-classic1.png
- \o \inlineimage qtwizard-modern1.png
- \o \inlineimage qtwizard-mac1.png
- \o \inlineimage qtwizard-aero1.png
- \row \o \inlineimage qtwizard-classic2.png
- \o \inlineimage qtwizard-modern2.png
- \o \inlineimage qtwizard-mac2.png
- \o \inlineimage qtwizard-aero2.png
+ \header \li ClassicStyle
+ \li ModernStyle
+ \li MacStyle
+ \li AeroStyle
+ \row \li \inlineimage qtwizard-classic1.png
+ \li \inlineimage qtwizard-modern1.png
+ \li \inlineimage qtwizard-mac1.png
+ \li \inlineimage qtwizard-aero1.png
+ \row \li \inlineimage qtwizard-classic2.png
+ \li \inlineimage qtwizard-modern2.png
+ \li \inlineimage qtwizard-mac2.png
+ \li \inlineimage qtwizard-aero2.png
\endtable
Note: AeroStyle has effect only on a Windows Vista system with alpha compositing enabled.
@@ -1876,15 +1876,15 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)
only one page is shown. A page has the following attributes:
\list
- \o A \l{QWizardPage::}{title}.
- \o A \l{QWizardPage::}{subTitle}.
- \o A set of pixmaps, which may or may not be honored, depending
+ \li A \l{QWizardPage::}{title}.
+ \li A \l{QWizardPage::}{subTitle}.
+ \li A set of pixmaps, which may or may not be honored, depending
on the wizard's style:
\list
- \o WatermarkPixmap (used by ClassicStyle and ModernStyle)
- \o BannerPixmap (used by ModernStyle)
- \o LogoPixmap (used by ClassicStyle and ModernStyle)
- \o BackgroundPixmap (used by MacStyle)
+ \li WatermarkPixmap (used by ClassicStyle and ModernStyle)
+ \li BannerPixmap (used by ModernStyle)
+ \li LogoPixmap (used by ClassicStyle and ModernStyle)
+ \li BackgroundPixmap (used by MacStyle)
\endlist
\endlist
@@ -2590,9 +2590,9 @@ bool QWizard::testOption(WizardOption option) const
By default, the following options are set (depending on the platform):
\list
- \o Windows: HelpButtonOnRight.
- \o Mac OS X: NoDefaultButton and NoCancelButton.
- \o X11 and QWS (Qt for Embedded Linux): none.
+ \li Windows: HelpButtonOnRight.
+ \li Mac OS X: NoDefaultButton and NoCancelButton.
+ \li X11 and QWS (Qt for Embedded Linux): none.
\endlist
\sa wizardStyle
@@ -2881,14 +2881,14 @@ QPixmap QWizard::pixmap(WizardPixmap which) const
changedSignal. The table below lists these widgets:
\table
- \header \o Widget \o Property \o Change Notification Signal
- \row \o QAbstractButton \o bool \l{QAbstractButton::}{checked} \o \l{QAbstractButton::}{toggled()}
- \row \o QAbstractSlider \o int \l{QAbstractSlider::}{value} \o \l{QAbstractSlider::}{valueChanged()}
- \row \o QComboBox \o int \l{QComboBox::}{currentIndex} \o \l{QComboBox::}{currentIndexChanged()}
- \row \o QDateTimeEdit \o QDateTime \l{QDateTimeEdit::}{dateTime} \o \l{QDateTimeEdit::}{dateTimeChanged()}
- \row \o QLineEdit \o QString \l{QLineEdit::}{text} \o \l{QLineEdit::}{textChanged()}
- \row \o QListWidget \o int \l{QListWidget::}{currentRow} \o \l{QListWidget::}{currentRowChanged()}
- \row \o QSpinBox \o int \l{QSpinBox::}{value} \o \l{QSpinBox::}{valueChanged()}
+ \header \li Widget \li Property \li Change Notification Signal
+ \row \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}
+ \row \li QAbstractSlider \li int \l{QAbstractSlider::}{value} \li \l{QAbstractSlider::}{valueChanged()}
+ \row \li QComboBox \li int \l{QComboBox::}{currentIndex} \li \l{QComboBox::}{currentIndexChanged()}
+ \row \li QDateTimeEdit \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}
+ \row \li QLineEdit \li QString \l{QLineEdit::}{text} \li \l{QLineEdit::}{textChanged()}
+ \row \li QListWidget \li int \l{QListWidget::}{currentRow} \li \l{QListWidget::}{currentRowChanged()}
+ \row \li QSpinBox \li int \l{QSpinBox::}{value} \li \l{QSpinBox::}{valueChanged()}
\endtable
\sa QWizardPage::registerField()
@@ -3141,7 +3141,12 @@ bool QWizard::event(QEvent *event)
#if !defined(QT_NO_STYLE_WINDOWSVISTA)
else if (event->type() == QEvent::Show && d->vistaInitPending) {
d->vistaInitPending = false;
- d->wizStyle = AeroStyle;
+ // Do not force AeroStyle when in Classic theme.
+ // Note that d->handleAeroStyleChange() needs to be called in any case as it does some
+ // necessary initialization, like ensures that the Aero specific back button is hidden if
+ // Aero theme isn't active.
+ if (QVistaHelper::vistaState() != QVistaHelper::Classic)
+ d->wizStyle = AeroStyle;
d->handleAeroStyleChange();
}
else if (d->isVistaThemeEnabled()) {
@@ -3356,19 +3361,19 @@ int QWizard::nextId() const
provide custom behavior:
\list
- \o initializePage() is called to initialize the page's contents
+ \li initializePage() is called to initialize the page's contents
when the user clicks the wizard's \gui Next button. If you
want to derive the page's default from what the user entered
on previous pages, this is the function to reimplement.
- \o cleanupPage() is called to reset the page's contents when the
+ \li cleanupPage() is called to reset the page's contents when the
user clicks the wizard's \gui Back button.
- \o validatePage() validates the page when the user clicks \gui
+ \li validatePage() validates the page when the user clicks \gui
Next or \gui Finish. It is often used to show an error message
if the user has entered incomplete or invalid information.
- \o nextId() returns the ID of the next page. It is useful when
+ \li nextId() returns the ID of the next page. It is useful when
\l{creating non-linear wizards}, which allow different
traversal paths based on the information provided by the user.
- \o isComplete() is called to determine whether the \gui Next
+ \li isComplete() is called to determine whether the \gui Next
and/or \gui Finish button should be enabled or disabled. If
you reimplement isComplete(), also make sure that
completeChanged() is emitted whenever the complete state
@@ -3873,14 +3878,14 @@ QVariant QWizardPage::field(const QString &name) const
changedSignal. The table below lists these widgets:
\table
- \header \o Widget \o Property \o Change Notification Signal
- \row \o QAbstractButton \o bool \l{QAbstractButton::}{checked} \o \l{QAbstractButton::}{toggled()}
- \row \o QAbstractSlider \o int \l{QAbstractSlider::}{value} \o \l{QAbstractSlider::}{valueChanged()}
- \row \o QComboBox \o int \l{QComboBox::}{currentIndex} \o \l{QComboBox::}{currentIndexChanged()}
- \row \o QDateTimeEdit \o QDateTime \l{QDateTimeEdit::}{dateTime} \o \l{QDateTimeEdit::}{dateTimeChanged()}
- \row \o QLineEdit \o QString \l{QLineEdit::}{text} \o \l{QLineEdit::}{textChanged()}
- \row \o QListWidget \o int \l{QListWidget::}{currentRow} \o \l{QListWidget::}{currentRowChanged()}
- \row \o QSpinBox \o int \l{QSpinBox::}{value} \o \l{QSpinBox::}{valueChanged()}
+ \header \li Widget \li Property \li Change Notification Signal
+ \row \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}
+ \row \li QAbstractSlider \li int \l{QAbstractSlider::}{value} \li \l{QAbstractSlider::}{valueChanged()}
+ \row \li QComboBox \li int \l{QComboBox::}{currentIndex} \li \l{QComboBox::}{currentIndexChanged()}
+ \row \li QDateTimeEdit \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}
+ \row \li QLineEdit \li QString \l{QLineEdit::}{text} \li \l{QLineEdit::}{textChanged()}
+ \row \li QListWidget \li int \l{QListWidget::}{currentRow} \li \l{QListWidget::}{currentRowChanged()}
+ \row \li QSpinBox \li int \l{QSpinBox::}{value} \li \l{QSpinBox::}{valueChanged()}
\endtable
You can use QWizard::setDefaultProperty() to add entries to this
diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp
index f1b4cc80f9..80c0aff492 100644
--- a/src/widgets/effects/qgraphicseffect.cpp
+++ b/src/widgets/effects/qgraphicseffect.cpp
@@ -62,21 +62,21 @@
Qt provides the following standard effects:
\list
- \o QGraphicsBlurEffect - blurs the item by a given radius
- \o QGraphicsDropShadowEffect - renders a dropshadow behind the item
- \o QGraphicsColorizeEffect - renders the item in shades of any given color
- \o QGraphicsOpacityEffect - renders the item with an opacity
+ \li QGraphicsBlurEffect - blurs the item by a given radius
+ \li QGraphicsDropShadowEffect - renders a dropshadow behind the item
+ \li QGraphicsColorizeEffect - renders the item in shades of any given color
+ \li QGraphicsOpacityEffect - renders the item with an opacity
\endlist
\table
\row
- \o{2,1} \img graphicseffect-plain.png
+ \li{2,1} \img graphicseffect-plain.png
\row
- \o \img graphicseffect-blur.png
- \o \img graphicseffect-colorize.png
+ \li \img graphicseffect-blur.png
+ \li \img graphicseffect-colorize.png
\row
- \o \img graphicseffect-opacity.png
- \o \img graphicseffect-drop-shadow.png
+ \li \img graphicseffect-opacity.png
+ \li \img graphicseffect-drop-shadow.png
\endtable
\img graphicseffect-widget.png
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
index 1ccf6fcffe..348d8f2d09 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
@@ -107,11 +107,11 @@
avoid any future regressions in behaviour:
\list
- \o Stretch factors are not respected.
+ \li Stretch factors are not respected.
- \o QSizePolicy::ExpandFlag is not respected.
+ \li QSizePolicy::ExpandFlag is not respected.
- \o Height for width is not respected.
+ \li Height for width is not respected.
\endlist
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index ab03ff7a9e..dab1965da5 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -59,14 +59,14 @@
common shapes. These are:
\list
- \o QGraphicsEllipseItem provides an ellipse item
- \o QGraphicsLineItem provides a line item
- \o QGraphicsPathItem provides an arbitrary path item
- \o QGraphicsPixmapItem provides a pixmap item
- \o QGraphicsPolygonItem provides a polygon item
- \o QGraphicsRectItem provides a rectangular item
- \o QGraphicsSimpleTextItem provides a simple text label item
- \o QGraphicsTextItem provides an advanced text browser item
+ \li QGraphicsEllipseItem provides an ellipse item
+ \li QGraphicsLineItem provides a line item
+ \li QGraphicsPathItem provides an arbitrary path item
+ \li QGraphicsPixmapItem provides a pixmap item
+ \li QGraphicsPolygonItem provides a polygon item
+ \li QGraphicsRectItem provides a rectangular item
+ \li QGraphicsSimpleTextItem provides a simple text label item
+ \li QGraphicsTextItem provides an advanced text browser item
\endlist
All of an item's geometric information is based on its local coordinate
@@ -112,12 +112,12 @@
\list 1
- \o Reimplement shape() to return an accurate shape for your item,
+ \li Reimplement shape() to return an accurate shape for your item,
and rely on the default implementation of collidesWithItem() to do
shape-shape intersection. This can be rather expensive if the
shapes are complex.
- \o Reimplement collidesWithItem() to provide your own custom item
+ \li Reimplement collidesWithItem() to provide your own custom item
and shape collision algorithm.
\endlist
@@ -165,10 +165,10 @@
QGraphicsItem always applies the properties in a fixed, defined order:
\list
- \o The item's base transform is applied (transform())
- \o The item's transformations list is applied in order (transformations())
- \o The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
- \o The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
+ \li The item's base transform is applied (transform())
+ \li The item's transformations list is applied in order (transformations())
+ \li The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
+ \li The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
\endlist
\section1 Painting
@@ -215,14 +215,14 @@
For advanced users, there are ways to alter how your items are sorted:
\list
- \o You can call setZValue() on an item to explicitly stack it on top of, or
+ \li You can call setZValue() on an item to explicitly stack it on top of, or
under, other sibling items. The default Z value for an item is 0. Items
with the same Z value are stacked by insertion order.
- \o You can call stackBefore() to reorder the list of children. This will
+ \li You can call stackBefore() to reorder the list of children. This will
directly modify the insertion order.
- \o You can set the ItemStacksBehindParent flag to stack a child item behind
+ \li You can set the ItemStacksBehindParent flag to stack a child item behind
its parent.
\endlist
@@ -238,13 +238,13 @@
to a set of convenience event handlers:
\list
- \o contextMenuEvent() handles context menu events
- \o focusInEvent() and focusOutEvent() handle focus in and out events
- \o hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
+ \li contextMenuEvent() handles context menu events
+ \li focusInEvent() and focusOutEvent() handle focus in and out events
+ \li hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
hover enter, move and leave events
- \o inputMethodEvent() handles input events, for accessibility support
- \o keyPressEvent() and keyReleaseEvent() handle key press and release events
- \o mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
+ \li inputMethodEvent() handles input events, for accessibility support
+ \li keyPressEvent() and keyReleaseEvent() handle key press and release events
+ \li mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
mouseDoubleClickEvent() handles mouse press, move, release, click and
doubleclick events
\endlist
@@ -783,7 +783,7 @@ static inline void _q_adjustRect(QRect *rect)
class QGraphicsItemCustomDataStore
{
public:
- QMap<const QGraphicsItem *, QMap<int, QVariant> > data;
+ QHash<const QGraphicsItem *, QMap<int, QVariant> > data;
};
Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
@@ -1379,7 +1379,7 @@ void QGraphicsItemCache::purge()
{
QPixmapCache::remove(key);
key = QPixmapCache::Key();
- QMutableMapIterator<QPaintDevice *, DeviceData> it(deviceData);
+ QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
while (it.hasNext()) {
DeviceData &data = it.next().value();
QPixmapCache::remove(data.key);
@@ -3469,11 +3469,11 @@ QGraphicsItem *QGraphicsItem::focusScopeItem() const
following events occurs:
\list
- \o The item becomes invisible
- \o The item is removed from the scene
- \o The item is deleted
- \o The item call ungrabMouse()
- \o Another item calls grabMouse(); the item will regain the mouse grab
+ \li The item becomes invisible
+ \li The item is removed from the scene
+ \li The item is deleted
+ \li The item call ungrabMouse()
+ \li Another item calls grabMouse(); the item will regain the mouse grab
when the other item calls ungrabMouse().
\endlist
@@ -3531,11 +3531,11 @@ void QGraphicsItem::ungrabMouse()
following events occur:
\list
- \o The item becomes invisible
- \o The item is removed from the scene
- \o The item is deleted
- \o The item calls ungrabKeyboard()
- \o Another item calls grabKeyboard(); the item will regain the keyboard grab
+ \li The item becomes invisible
+ \li The item is removed from the scene
+ \li The item is deleted
+ \li The item calls ungrabKeyboard()
+ \li Another item calls grabKeyboard(); the item will regain the keyboard grab
when the other item calls ungrabKeyboard().
\endlist
@@ -5730,7 +5730,7 @@ void QGraphicsItem::update(const QRectF &rect)
viewport, which does not benefit from scroll optimizations), this function
is equivalent to calling update(\a rect).
- \bold{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
+ \b{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
is enabled; in all other cases calling this function is equivalent to calling
update(\a rect). If you for sure know that the item is opaque and not overlapped
by other items, you can map the \a rect to viewport coordinates and scroll the
@@ -7124,7 +7124,7 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
// Determine the list of items that need to be moved.
QList<QGraphicsItem *> selectedItems;
- QMap<QGraphicsItem *, QPointF> initialPositions;
+ QHash<QGraphicsItem *, QPointF> initialPositions;
if (d_ptr->scene) {
selectedItems = d_ptr->scene->selectedItems();
initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
@@ -8652,8 +8652,8 @@ QVariant QGraphicsRectItem::extension(const QVariant &variant) const
\table
\row
- \o \inlineimage graphicsview-ellipseitem.png
- \o \inlineimage graphicsview-ellipseitem-pie.png
+ \li \inlineimage graphicsview-ellipseitem.png
+ \li \inlineimage graphicsview-ellipseitem-pie.png
\endtable
To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index aebb22a0ee..1783fdb713 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -145,7 +145,7 @@ public:
QPoint cacheIndent;
QPixmapCache::Key key;
};
- QMap<QPaintDevice *, DeviceData> deviceData;
+ QHash<QPaintDevice *, DeviceData> deviceData;
// List of logical exposed rects
QVector<QRectF> exposed;
@@ -508,7 +508,7 @@ public:
QRectF childrenBoundingRect;
QRectF needsRepaint;
- QMap<QWidget *, QRect> paintedViewBoundingRects;
+ QHash<QWidget *, QRect> paintedViewBoundingRects;
QPointF pos;
qreal z;
qreal opacity;
diff --git a/src/widgets/graphicsview/qgraphicslayout.cpp b/src/widgets/graphicsview/qgraphicslayout.cpp
index 63f04f67bc..6f93dd511d 100644
--- a/src/widgets/graphicsview/qgraphicslayout.cpp
+++ b/src/widgets/graphicsview/qgraphicslayout.cpp
@@ -77,19 +77,19 @@ QT_BEGIN_NAMESPACE
minimum:
\table
- \header \o Function \o Description
- \row \o QGraphicsLayoutItem::setGeometry()
- \o Notifies you when the geometry of the layout is set. You can
+ \header \li Function \li Description
+ \row \li QGraphicsLayoutItem::setGeometry()
+ \li Notifies you when the geometry of the layout is set. You can
store the geometry in your own layout class in a reimplementation
of this function.
- \row \o QGraphicsLayoutItem::sizeHint()
- \o Returns the layout's size hints.
- \row \o QGraphicsLayout::count()
- \o Returns the number of items in your layout.
- \row \o QGraphicsLayout::itemAt()
- \o Returns a pointer to an item in your layout.
- \row \o QGraphicsLayout::removeAt()
- \o Removes an item from your layout without destroying it.
+ \row \li QGraphicsLayoutItem::sizeHint()
+ \li Returns the layout's size hints.
+ \row \li QGraphicsLayout::count()
+ \li Returns the number of items in your layout.
+ \row \li QGraphicsLayout::itemAt()
+ \li Returns a pointer to an item in your layout.
+ \row \li QGraphicsLayout::removeAt()
+ \li Removes an item from your layout without destroying it.
\endtable
For more details on how to implement each function, refer to the individual
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index d532c4e541..4cda3e51fb 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -136,45 +136,45 @@ QT_BEGIN_NAMESPACE
QGraphicsProxyWidget maintains symmetry for the following states:
\table
- \header \o QWidget state \o QGraphicsProxyWidget state \o Notes
- \row \o QWidget::enabled
- \o QGraphicsProxyWidget::enabled
- \o
- \row \o QWidget::visible
- \o QGraphicsProxyWidget::visible
- \o The explicit state is also symmetric.
- \row \o QWidget::geometry
- \o QGraphicsProxyWidget::geometry
- \o Geometry is only guaranteed to be symmetric while
+ \header \li QWidget state \li QGraphicsProxyWidget state \li Notes
+ \row \li QWidget::enabled
+ \li QGraphicsProxyWidget::enabled
+ \li
+ \row \li QWidget::visible
+ \li QGraphicsProxyWidget::visible
+ \li The explicit state is also symmetric.
+ \row \li QWidget::geometry
+ \li QGraphicsProxyWidget::geometry
+ \li Geometry is only guaranteed to be symmetric while
the embedded widget is visible.
- \row \o QWidget::layoutDirection
- \o QGraphicsProxyWidget::layoutDirection
- \o
- \row \o QWidget::style
- \o QGraphicsProxyWidget::style
- \o
- \row \o QWidget::palette
- \o QGraphicsProxyWidget::palette
- \o
- \row \o QWidget::font
- \o QGraphicsProxyWidget::font
- \o
- \row \o QWidget::cursor
- \o QGraphicsProxyWidget::cursor
- \o The embedded widget overrides the proxy widget
+ \row \li QWidget::layoutDirection
+ \li QGraphicsProxyWidget::layoutDirection
+ \li
+ \row \li QWidget::style
+ \li QGraphicsProxyWidget::style
+ \li
+ \row \li QWidget::palette
+ \li QGraphicsProxyWidget::palette
+ \li
+ \row \li QWidget::font
+ \li QGraphicsProxyWidget::font
+ \li
+ \row \li QWidget::cursor
+ \li QGraphicsProxyWidget::cursor
+ \li The embedded widget overrides the proxy widget
cursor. The proxy cursor changes depending on
which embedded subwidget is currently under the
mouse.
- \row \o QWidget::sizeHint()
- \o QGraphicsProxyWidget::sizeHint()
- \o All size hint functionality from the embedded
+ \row \li QWidget::sizeHint()
+ \li QGraphicsProxyWidget::sizeHint()
+ \li All size hint functionality from the embedded
widget is forwarded by the proxy.
- \row \o QWidget::getContentsMargins()
- \o QGraphicsProxyWidget::getContentsMargins()
- \o Updated once by setWidget().
- \row \o QWidget::windowTitle
- \o QGraphicsProxyWidget::windowTitle
- \o Updated once by setWidget().
+ \row \li QWidget::getContentsMargins()
+ \li QGraphicsProxyWidget::getContentsMargins()
+ \li Updated once by setWidget().
+ \row \li QWidget::windowTitle
+ \li QGraphicsProxyWidget::windowTitle
+ \li Updated once by setWidget().
\endtable
\note QGraphicsScene keeps the embedded widget in a special state that
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 280aa7af8e..015cd254d4 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -1082,7 +1082,7 @@ void QGraphicsScenePrivate::enableMouseTrackingOnViews()
/*!
Returns all items for the screen position in \a event.
*/
-QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/,
+QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &screenPos,
const QPointF &scenePos,
QWidget *widget) const
{
@@ -1091,12 +1091,16 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*sc
if (!view)
return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
- const QRectF pointRect(scenePos, QSizeF(1, 1));
+ const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));
if (!view->isTransformed())
return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
const QTransform viewTransform = view->viewportTransform();
- return q->items(pointRect, Qt::IntersectsItemShape,
+ if (viewTransform.type() <= QTransform::TxScale) {
+ return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape,
+ Qt::DescendingOrder, viewTransform);
+ }
+ return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape,
Qt::DescendingOrder, viewTransform);
}
@@ -3114,12 +3118,12 @@ bool QGraphicsScene::stickyFocus() const
the following events occur:
\list
- \o If the item receives a mouse release event when there are no other
+ \li If the item receives a mouse release event when there are no other
buttons pressed, it loses the mouse grab.
- \o If the item becomes invisible (i.e., someone calls \c {item->setVisible(false)}),
+ \li If the item becomes invisible (i.e., someone calls \c {item->setVisible(false)}),
or if it becomes disabled (i.e., someone calls \c {item->setEnabled(false)}),
it loses the mouse grab.
- \o If the item is removed from the scene, it loses the mouse grab.
+ \li If the item is removed from the scene, it loses the mouse grab.
\endlist
If the item loses its mouse grab, the scene will ignore all mouse events
diff --git a/src/widgets/graphicsview/qgraphicsscene_p.h b/src/widgets/graphicsview/qgraphicsscene_p.h
index b0410e38ce..0f5a0a6fc1 100644
--- a/src/widgets/graphicsview/qgraphicsscene_p.h
+++ b/src/widgets/graphicsview/qgraphicsscene_p.h
@@ -128,7 +128,7 @@ public:
QVector<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
- QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
+ QHash<QGraphicsItem *, QPointF> movingItemsInitialPositions;
void registerTopLevelItem(QGraphicsItem *item);
void unregisterTopLevelItem(QGraphicsItem *item);
void _q_updateLater();
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index c179aeff2b..4ad8513050 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -81,10 +81,10 @@ QT_BEGIN_NAMESPACE
over QGraphicsItem. It is similar to QWidget in many ways:
\list
- \o Provides a \l palette, a \l font and a \l style().
- \o Has a defined geometry().
- \o Supports layouts with setLayout() and layout().
- \o Supports shortcuts and actions with grabShortcut() and insertAction()
+ \li Provides a \l palette, a \l font and a \l style().
+ \li Has a defined geometry().
+ \li Supports layouts with setLayout() and layout().
+ \li Supports shortcuts and actions with grabShortcut() and insertAction()
\endlist
Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
@@ -106,23 +106,23 @@ QT_BEGIN_NAMESPACE
Noticeable differences between QGraphicsWidget and QWidget are:
\table
- \header \o QGraphicsWidget
- \o QWidget
- \row \o Coordinates and geometry are defined with qreals (doubles or
+ \header \li QGraphicsWidget
+ \li QWidget
+ \row \li Coordinates and geometry are defined with qreals (doubles or
floats, depending on the platform).
- \o QWidget uses integer geometry (QPoint, QRect).
- \row \o The widget is already visible by default; you do not have to
+ \li QWidget uses integer geometry (QPoint, QRect).
+ \row \li The widget is already visible by default; you do not have to
call show() to display the widget.
- \o QWidget is hidden by default until you call show().
- \row \o A subset of widget attributes are supported.
- \o All widget attributes are supported.
- \row \o A top-level item's style defaults to QGraphicsScene::style
- \o A top-level widget's style defaults to QApplication::style
- \row \o Graphics View provides a custom drag and drop framework, different
+ \li QWidget is hidden by default until you call show().
+ \row \li A subset of widget attributes are supported.
+ \li All widget attributes are supported.
+ \row \li A top-level item's style defaults to QGraphicsScene::style
+ \li A top-level widget's style defaults to QApplication::style
+ \row \li Graphics View provides a custom drag and drop framework, different
from QWidget.
- \o Standard drag and drop framework.
- \row \o Widget items do not support modality.
- \o Full modality support.
+ \li Standard drag and drop framework.
+ \row \li Widget items do not support modality.
+ \li Full modality support.
\endtable
QGraphicsWidget supports a subset of Qt's widget attributes,
@@ -130,32 +130,32 @@ QT_BEGIN_NAMESPACE
listed in this table are unsupported, or otherwise unused.
\table
- \header \o Widget Attribute \o Usage
- \row \o Qt::WA_SetLayoutDirection
- \o Set by setLayoutDirection(), cleared by
+ \header \li Widget Attribute \li Usage
+ \row \li Qt::WA_SetLayoutDirection
+ \li Set by setLayoutDirection(), cleared by
unsetLayoutDirection(). You can test this attribute to
check if the widget has been explicitly assigned a
\l{QGraphicsWidget::layoutDirection()}
{layoutDirection}. If the attribute is not set, the
\l{QGraphicsWidget::layoutDirection()}
{layoutDirection()} is inherited.
- \row \o Qt::WA_RightToLeft
- \o Toggled by setLayoutDirection(). Inherited from the
+ \row \li Qt::WA_RightToLeft
+ \li Toggled by setLayoutDirection(). Inherited from the
parent/scene. If set, the widget's layout will order
horizontally arranged widgets from right to left.
- \row \o Qt::WA_SetStyle
- \o Set and cleared by setStyle(). If this attribute is
+ \row \li Qt::WA_SetStyle
+ \li Set and cleared by setStyle(). If this attribute is
set, the widget has been explicitly assigned a style.
If it is unset, the widget will use the scene's or the
application's style.
- \row \o Qt::WA_Resized
- \o Set by setGeometry() and resize().
- \row \o Qt::WA_SetPalette
- \o Set by setPalette().
- \row \o Qt::WA_SetFont
- \o Set by setFont().
- \row \o Qt::WA_WindowPropagation
- \o Enables propagation to window widgets.
+ \row \li Qt::WA_Resized
+ \li Set by setGeometry() and resize().
+ \row \li Qt::WA_SetPalette
+ \li Set by setPalette().
+ \row \li Qt::WA_SetFont
+ \li Set by setFont().
+ \row \li Qt::WA_WindowPropagation
+ \li Enables propagation to window widgets.
\endtable
Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
@@ -222,7 +222,7 @@ public:
}
private:
- QMap<const QGraphicsWidget *, QStyle *> styles;
+ QHash<const QGraphicsWidget *, QStyle *> styles;
mutable QMutex mutex;
};
Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)
@@ -646,29 +646,29 @@ QRectF QGraphicsWidget::windowFrameRect() const
\table
\header
- \o Style Option Property
- \o Value
+ \li Style Option Property
+ \li Value
\row
- \o state & QStyle::State_Enabled
- \o Corresponds to QGraphicsItem::isEnabled().
+ \li state & QStyle::State_Enabled
+ \li Corresponds to QGraphicsItem::isEnabled().
\row
- \o state & QStyle::State_HasFocus
- \o Corresponds to QGraphicsItem::hasFocus().
+ \li state & QStyle::State_HasFocus
+ \li Corresponds to QGraphicsItem::hasFocus().
\row
- \o state & QStyle::State_MouseOver
- \o Corresponds to QGraphicsItem::isUnderMouse().
+ \li state & QStyle::State_MouseOver
+ \li Corresponds to QGraphicsItem::isUnderMouse().
\row
- \o direction
- \o Corresponds to QGraphicsWidget::layoutDirection().
+ \li direction
+ \li Corresponds to QGraphicsWidget::layoutDirection().
\row
- \o rect
- \o Corresponds to QGraphicsWidget::rect().toRect().
+ \li rect
+ \li Corresponds to QGraphicsWidget::rect().toRect().
\row
- \o palette
- \o Corresponds to QGraphicsWidget::palette().
+ \li palette
+ \li Corresponds to QGraphicsWidget::palette().
\row
- \o fontMetrics
- \o Corresponds to QFontMetrics(QGraphicsWidget::font()).
+ \li fontMetrics
+ \li Corresponds to QFontMetrics(QGraphicsWidget::font()).
\endtable
Subclasses of QGraphicsWidget should call the base implementation, and
@@ -1201,11 +1201,11 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
QGraphicsWidget delivers notifications for the following properties:
- \table \o propertyName \o Property
- \row \o layoutDirection \o QGraphicsWidget::layoutDirection
- \row \o size \o QGraphicsWidget::size
- \row \o font \o QGraphicsWidget::font
- \row \o palette \o QGraphicsWidget::palette
+ \table \li propertyName \li Property
+ \row \li layoutDirection \li QGraphicsWidget::layoutDirection
+ \row \li size \li QGraphicsWidget::size
+ \row \li font \li QGraphicsWidget::font
+ \row \li palette \li QGraphicsWidget::palette
\endtable
\sa itemChange()
@@ -1347,33 +1347,33 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos)
Handles the \a event. QGraphicsWidget handles the following
events:
- \table \o Event \o Usage
- \row \o Polish
- \o Delivered to the widget some time after it has been
+ \table \li Event \li Usage
+ \row \li Polish
+ \li Delivered to the widget some time after it has been
shown.
- \row \o GraphicsSceneMove
- \o Delivered to the widget after its local position has
+ \row \li GraphicsSceneMove
+ \li Delivered to the widget after its local position has
changed.
- \row \o GraphicsSceneResize
- \o Delivered to the widget after its size has changed.
- \row \o Show
- \o Delivered to the widget before it has been shown.
- \row \o Hide
- \o Delivered to the widget after it has been hidden.
- \row \o PaletteChange
- \o Delivered to the widget after its palette has changed.
- \row \o FontChange
- \o Delivered to the widget after its font has changed.
- \row \o EnabledChange
- \o Delivered to the widget after its enabled state has
+ \row \li GraphicsSceneResize
+ \li Delivered to the widget after its size has changed.
+ \row \li Show
+ \li Delivered to the widget before it has been shown.
+ \row \li Hide
+ \li Delivered to the widget after it has been hidden.
+ \row \li PaletteChange
+ \li Delivered to the widget after its palette has changed.
+ \row \li FontChange
+ \li Delivered to the widget after its font has changed.
+ \row \li EnabledChange
+ \li Delivered to the widget after its enabled state has
changed.
- \row \o StyleChange
- \o Delivered to the widget after its style has changed.
- \row \o LayoutDirectionChange
- \o Delivered to the widget after its layout direction has
+ \row \li StyleChange
+ \li Delivered to the widget after its style has changed.
+ \row \li LayoutDirectionChange
+ \li Delivered to the widget after its layout direction has
changed.
- \row \o ContentsRectChange
- \o Delivered to the widget after its contents margins/
+ \row \li ContentsRectChange
+ \li Delivered to the widget after its contents margins/
contents rect has changed.
\endtable
*/
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index ff3de308e5..8530e2c23e 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -251,34 +251,34 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
\table
\header
- \o Keys
- \o Functionality
+ \li Keys
+ \li Functionality
\row
- \o Arrow keys
- \o Changes the current item and selects it.
+ \li Arrow keys
+ \li Changes the current item and selects it.
\row
- \o Ctrl+Arrow keys
- \o Changes the current item but does not select it.
+ \li Ctrl+Arrow keys
+ \li Changes the current item but does not select it.
\row
- \o Shift+Arrow keys
- \o Changes the current item and selects it. The previously
+ \li Shift+Arrow keys
+ \li Changes the current item and selects it. The previously
selected item(s) is not deselected.
\row
- \o Ctr+Space
- \o Toggles selection of the current item.
+ \li Ctr+Space
+ \li Toggles selection of the current item.
\row
- \o Tab/Backtab
- \o Changes the current item to the next/previous item.
+ \li Tab/Backtab
+ \li Changes the current item to the next/previous item.
\row
- \o Home/End
- \o Selects the first/last item in the model.
+ \li Home/End
+ \li Selects the first/last item in the model.
\row
- \o Page up/Page down
- \o Scrolls the rows shown up/down by the number of
+ \li Page up/Page down
+ \li Scrolls the rows shown up/down by the number of
visible rows in the view.
\row
- \o Ctrl+A
- \o Selects all items in the model.
+ \li Ctrl+A
+ \li Selects all items in the model.
\endtable
Note that the above table assumes that the
@@ -1428,7 +1428,7 @@ bool QAbstractItemView::dragEnabled() const
\value DragOnly The view supports dragging of its own items
\value DropOnly The view accepts drops
\value DragDrop The view supports both dragging and dropping
- \value InternalMove The view accepts move (\bold{not copy}) operations only
+ \value InternalMove The view accepts move (\b{not copy}) operations only
from itself.
Note that the model used needs to provide support for drag and drop operations.
diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp
index e4eca4287b..2f7b1f7ecb 100644
--- a/src/widgets/itemviews/qdatawidgetmapper.cpp
+++ b/src/widgets/itemviews/qdatawidgetmapper.cpp
@@ -279,11 +279,11 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed()
Let us assume that we have an item model named \c{model} with the following contents:
\table
- \row \o 1 \o Qt Norway \o Oslo
- \row \o 2 \o Qt Australia \o Brisbane
- \row \o 3 \o Qt USA \o Palo Alto
- \row \o 4 \o Qt China \o Beijing
- \row \o 5 \o Qt Germany \o Berlin
+ \row \li 1 \li Qt Norway \li Oslo
+ \row \li 2 \li Qt Australia \li Brisbane
+ \row \li 3 \li Qt USA \li Palo Alto
+ \row \li 4 \li Qt China \li Beijing
+ \row \li 5 \li Qt Germany \li Berlin
\endtable
The following code will map the columns of the model to widgets called \c mySpinBox,
@@ -478,11 +478,11 @@ QModelIndex QDataWidgetMapper::rootIndex() const
\snippet doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp 1
- \bold{Notes:}
+ \b{Notes:}
\list
- \o If the \a widget is already mapped to a section, the
+ \li If the \a widget is already mapped to a section, the
old mapping will be replaced by the new one.
- \o Only one-to-one mappings between sections and widgets are allowed.
+ \li Only one-to-one mappings between sections and widgets are allowed.
It is not possible to map a single section to multiple widgets, or to
map a single widget to multiple sections.
\endlist
@@ -781,11 +781,11 @@ void QDataWidgetMapper::clearMapping()
Use Qt::Horizontal for tabular data that looks like this:
\table
- \row \o 1 \o Qt Norway \o Oslo
- \row \o 2 \o Qt Australia \o Brisbane
- \row \o 3 \o Qt USA \o Silicon Valley
- \row \o 4 \o Qt China \o Beijing
- \row \o 5 \o Qt Germany \o Berlin
+ \row \li 1 \li Qt Norway \li Oslo
+ \row \li 2 \li Qt Australia \li Brisbane
+ \row \li 3 \li Qt USA \li Silicon Valley
+ \row \li 4 \li Qt China \li Beijing
+ \row \li 5 \li Qt Germany \li Berlin
\endtable
If the orientation is set to Qt::Vertical, a widget is mapped to
@@ -796,9 +796,9 @@ void QDataWidgetMapper::clearMapping()
Use Qt::Vertical for tabular data that looks like this:
\table
- \row \o 1 \o 2 \o 3 \o 4 \o 5
- \row \o Qt Norway \o Qt Australia \o Qt USA \o Qt China \o Qt Germany
- \row \o Oslo \o Brisbane \o Silicon Valley \o Beijing \i Berlin
+ \row \li 1 \li 2 \li 3 \li 4 \li 5
+ \row \li Qt Norway \li Qt Australia \li Qt USA \li Qt China \li Qt Germany
+ \row \li Oslo \li Brisbane \li Silicon Valley \li Beijing \li Berlin
\endtable
Changing the orientation clears all existing mappings.
diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp
index ee097e5c41..490c272e39 100644
--- a/src/widgets/itemviews/qdirmodel.cpp
+++ b/src/widgets/itemviews/qdirmodel.cpp
@@ -1011,12 +1011,12 @@ QModelIndex QDirModel::mkdir(const QModelIndex &parent, const QString &name)
/*!
Removes the directory corresponding to the model item \a index in the
- directory model and \bold{deletes the corresponding directory from the
+ directory model and \b{deletes the corresponding directory from the
file system}, returning true if successful. If the directory cannot be
removed, false is returned.
\warning This function deletes directories from the file system; it does
- \bold{not} move them to a location where they can be recovered.
+ \b{not} move them to a location where they can be recovered.
\sa remove()
*/
@@ -1046,11 +1046,11 @@ bool QDirModel::rmdir(const QModelIndex &index)
}
/*!
- Removes the model item \a index from the directory model and \bold{deletes the
+ Removes the model item \a index from the directory model and \b{deletes the
corresponding file from the file system}, returning true if successful. If the
item cannot be removed, false is returned.
- \warning This function deletes files from the file system; it does \bold{not}
+ \warning This function deletes files from the file system; it does \b{not}
move them to a location where they can be recovered.
\sa rmdir()
@@ -1134,7 +1134,7 @@ QIcon QDirModel::fileIcon(const QModelIndex &index) const
/*!
Returns the file information for the specified model \a index.
- \bold{Note:} If the model index represents a symbolic link in the
+ \b{Note:} If the model index represents a symbolic link in the
underlying filing system, the file information returned will contain
information about the symbolic link itself, regardless of whether
resolveSymlinks is enabled or not.
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 5d2aceaade..eac543d37d 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -490,7 +490,7 @@ void QHeaderView::setOffset(int newOffset)
void QHeaderView::setOffsetToSectionPosition(int visualSectionNumber)
{
Q_D(QHeaderView);
- if (visualSectionNumber > -1 && visualSectionNumber < d->sectionCount) {
+ if (visualSectionNumber > -1 && visualSectionNumber < d->sectionCount()) {
int position = d->headerSectionPosition(d->adjustedVisualIndex(visualSectionNumber));
setOffset(position);
}
@@ -597,7 +597,7 @@ int QHeaderView::visualIndexAt(int position) const
int vposition = position;
d->executePostedLayout();
d->executePostedResize();
- const int count = d->sectionCount;
+ const int count = d->sectionCount();
if (count < 1)
return -1;
@@ -728,7 +728,7 @@ void QHeaderView::moveSection(int from, int to)
Q_D(QHeaderView);
d->executePostedLayout();
- if (from < 0 || from >= d->sectionCount || to < 0 || to >= d->sectionCount)
+ if (from < 0 || from >= d->sectionCount() || to < 0 || to >= d->sectionCount())
return;
if (from == to) {
@@ -828,7 +828,7 @@ void QHeaderView::swapSections(int first, int second)
if (first == second)
return;
d->executePostedLayout();
- if (first < 0 || first >= d->sectionCount || second < 0 || second >= d->sectionCount)
+ if (first < 0 || first >= d->sectionCount() || second < 0 || second >= d->sectionCount())
return;
int firstSize = d->headerSectionSize(first);
@@ -965,7 +965,7 @@ bool QHeaderView::isSectionHidden(int logicalIndex) const
{
Q_D(const QHeaderView);
d->executePostedLayout();
- if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount)
+ if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount())
return false;
int visual = visualIndex(logicalIndex);
Q_ASSERT(visual != -1);
@@ -1038,7 +1038,7 @@ int QHeaderView::count() const
//Q_ASSERT(d->sectionCount == d->headerSectionCount());
// ### this may affect the lazy layout
d->executePostedLayout();
- return d->sectionCount;
+ return d->sectionCount();
}
/*!
@@ -1057,11 +1057,11 @@ int QHeaderView::visualIndex(int logicalIndex) const
return -1;
d->executePostedLayout();
if (d->visualIndices.isEmpty()) { // nothing has been moved, so we have no mapping
- if (logicalIndex < d->sectionCount)
+ if (logicalIndex < d->sectionCount())
return logicalIndex;
} else if (logicalIndex < d->visualIndices.count()) {
int visual = d->visualIndices.at(logicalIndex);
- Q_ASSERT(visual < d->sectionCount);
+ Q_ASSERT(visual < d->sectionCount());
return visual;
}
return -1;
@@ -1079,7 +1079,7 @@ int QHeaderView::visualIndex(int logicalIndex) const
int QHeaderView::logicalIndex(int visualIndex) const
{
Q_D(const QHeaderView);
- if (visualIndex < 0 || visualIndex >= d->sectionCount)
+ if (visualIndex < 0 || visualIndex >= d->sectionCount())
return -1;
return d->logicalIndex(visualIndex);
}
@@ -1293,14 +1293,14 @@ void QHeaderView::setSortIndicator(int logicalIndex, Qt::SortOrder order)
d->sortIndicatorSection = logicalIndex;
d->sortIndicatorOrder = order;
- if (logicalIndex >= d->sectionCount) {
+ if (logicalIndex >= d->sectionCount()) {
emit sortIndicatorChanged(logicalIndex, order);
return; // nothing to do
}
if (old != logicalIndex
&& ((logicalIndex >= 0 && resizeMode(logicalIndex) == ResizeToContents)
- || old >= d->sectionCount || (old >= 0 && resizeMode(old) == ResizeToContents))) {
+ || old >= d->sectionCount() || (old >= 0 && resizeMode(old) == ResizeToContents))) {
resizeSections();
d->viewport->update();
} else {
@@ -1655,15 +1655,14 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
Q_D(QHeaderView);
if (parent != d->root)
return; // we only handle changes in the top level
- int oldCount = d->sectionCount;
+ int oldCount = d->sectionCount();
d->invalidateCachedSizeHint();
// add the new sections
int insertAt = logicalFirst;
-
int insertCount = logicalLast - logicalFirst + 1;
- d->sectionCount += insertCount;
+
QHeaderViewPrivate::SectionSpan span(d->defaultSectionSize, d->globalResizeMode);
d->sectionStartposRecalc = true;
@@ -1684,9 +1683,9 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
// update resize mode section counts
if (d->globalResizeMode == Stretch)
- d->stretchSections = d->sectionCount;
+ d->stretchSections = d->sectionCount();
else if (d->globalResizeMode == ResizeToContents)
- d->contentsSections = d->sectionCount;
+ d->contentsSections = d->sectionCount();
// clear selection cache
d->sectionSelected.clear();
@@ -1723,7 +1722,7 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
for (int i = 0; i < logicalFirst; ++i)
if (isSectionHidden(i))
newHiddenSectionSize[i] = d->hiddenSectionSize[i];
- for (int j = logicalLast + 1; j < d->sectionCount; ++j)
+ for (int j = logicalLast + 1; j < d->sectionCount(); ++j)
if (isSectionHidden(j))
newHiddenSectionSize[j] = d->hiddenSectionSize[j - insertCount];
d->hiddenSectionSize = newHiddenSectionSize;
@@ -1762,14 +1761,14 @@ void QHeaderViewPrivate::updateHiddenSections(int logicalFirst, int logicalLast)
for (int i = 0; i < logicalFirst; ++i)
if (q->isSectionHidden(i))
newHiddenSectionSize[i] = hiddenSectionSize[i];
- for (int j = logicalLast + 1; j < sectionCount; ++j)
+ for (int j = logicalLast + 1; j < sectionCount(); ++j)
if (q->isSectionHidden(j))
newHiddenSectionSize[j - changeCount] = hiddenSectionSize[j];
hiddenSectionSize = newHiddenSectionSize;
// remove sections from sectionsHidden
if (!sectionHidden.isEmpty()) {
- const int newsize = qMin(sectionCount - changeCount, sectionHidden.size());
+ const int newsize = qMin(sectionCount() - changeCount, sectionHidden.size());
QBitArray newSectionHidden(newsize);
for (int j = 0, k = 0; j < sectionHidden.size(); ++j) {
const int logical = logicalIndex(j);
@@ -1788,7 +1787,7 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
if (parent != root)
return; // we only handle changes in the top level
if (qMin(logicalFirst, logicalLast) < 0
- || qMax(logicalLast, logicalFirst) >= sectionCount)
+ || qMax(logicalLast, logicalFirst) >= sectionCount())
return;
int oldCount = q->count();
int changeCount = logicalLast - logicalFirst + 1;
@@ -1802,8 +1801,8 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
if (logicalFirst == logicalLast) { // Remove just one index.
int l = logicalFirst;
int visual = visualIndices.at(l);
- Q_ASSERT(sectionCount == logicalIndices.count());
- for (int v = 0; v < sectionCount; ++v) {
+ Q_ASSERT(sectionCount() == logicalIndices.count());
+ for (int v = 0; v < sectionCount(); ++v) {
if (v > visual) {
int logical = logicalIndices.at(v);
--(visualIndices[logical]);
@@ -1837,7 +1836,6 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
}
// ### handle sectionSelection (sectionHidden is handled by updateHiddenSections)
}
- sectionCount -= changeCount;
// update sorting column
if (sortIndicatorSection >= logicalFirst) {
@@ -1848,7 +1846,7 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
}
// if we only have the last section (the "end" position) left, the header is empty
- if (sectionCount <= 0)
+ if (sectionCount() <= 0)
clear();
invalidateCachedSizeHint();
emit q->sectionCountChanged(oldCount, q->count());
@@ -1877,7 +1875,7 @@ void QHeaderViewPrivate::_q_layoutChanged()
Q_Q(QHeaderView);
viewport->update();
if (persistentHiddenSections.isEmpty() || modelIsEmpty()) {
- if (modelSectionCount() != sectionCount)
+ if (modelSectionCount() != sectionCount())
q->initializeSections();
persistentHiddenSections.clear();
return;
@@ -1894,7 +1892,7 @@ void QHeaderViewPrivate::_q_layoutChanged()
: index.row());
q->setSectionHidden(logical, true);
oldSectionHidden.setBit(logical, false);
- } else if (!sectionCountChanged && (modelSectionCount() != sectionCount)) {
+ } else if (!sectionCountChanged && (modelSectionCount() != sectionCount())) {
sectionCountChanged = true;
break;
}
@@ -1918,7 +1916,7 @@ void QHeaderViewPrivate::_q_layoutChanged()
void QHeaderView::initializeSections()
{
Q_D(QHeaderView);
- const int oldCount = d->sectionCount;
+ const int oldCount = d->sectionCount();
const int newCount = d->modelSectionCount();
if (newCount <= 0) {
d->clear();
@@ -1927,7 +1925,7 @@ void QHeaderView::initializeSections()
const int min = qBound(0, oldCount, newCount - 1);
initializeSections(min, newCount - 1);
if (stretchLastSection()) // we've already gotten the size hint
- d->lastSectionSize = sectionSize(logicalIndex(d->sectionCount - 1));
+ d->lastSectionSize = sectionSize(logicalIndex(d->sectionCount() - 1));
//make sure we update the hidden sections
if (newCount < oldCount)
@@ -1947,13 +1945,14 @@ void QHeaderView::initializeSections(int start, int end)
Q_ASSERT(end >= 0);
d->invalidateCachedSizeHint();
+ int oldCount = d->sectionCount();
- if (end + 1 < d->sectionCount) {
+ if (end + 1 < d->sectionCount()) {
int newCount = end + 1;
- d->removeSectionsFromSpans(newCount, d->sectionCount - 1);
+ d->removeSectionsFromSpans(newCount, d->sectionCount() - 1);
if (!d->hiddenSectionSize.isEmpty()) {
- if (d->sectionCount - newCount > d->hiddenSectionSize.count()) {
- for (int i = end + 1; i < d->sectionCount; ++i)
+ if (oldCount - newCount > d->hiddenSectionSize.count()) {
+ for (int i = end + 1; i < d->sectionCount(); ++i)
d->hiddenSectionSize.remove(i);
} else {
QHash<int, int>::iterator it = d->hiddenSectionSize.begin();
@@ -1967,14 +1966,13 @@ void QHeaderView::initializeSections(int start, int end)
}
}
- int oldCount = d->sectionCount;
- d->sectionCount = end + 1;
+ int newSectionCount = end + 1;
if (!d->logicalIndices.isEmpty()) {
- if (oldCount <= d->sectionCount) {
- d->logicalIndices.resize(d->sectionCount);
- d->visualIndices.resize(d->sectionCount);
- for (int i = oldCount; i < d->sectionCount; ++i) {
+ if (oldCount <= newSectionCount) {
+ d->logicalIndices.resize(newSectionCount);
+ d->visualIndices.resize(newSectionCount);
+ for (int i = oldCount; i < newSectionCount; ++i) {
d->logicalIndices[i] = i;
d->visualIndices[i] = i;
}
@@ -1982,30 +1980,30 @@ void QHeaderView::initializeSections(int start, int end)
int j = 0;
for (int i = 0; i < oldCount; ++i) {
int v = d->logicalIndices.at(i);
- if (v < d->sectionCount) {
+ if (v < newSectionCount) {
d->logicalIndices[j] = v;
d->visualIndices[v] = j;
j++;
}
}
- d->logicalIndices.resize(d->sectionCount);
- d->visualIndices.resize(d->sectionCount);
+ d->logicalIndices.resize(newSectionCount);
+ d->visualIndices.resize(newSectionCount);
}
}
if (d->globalResizeMode == Stretch)
- d->stretchSections = d->sectionCount;
+ d->stretchSections = newSectionCount;
else if (d->globalResizeMode == ResizeToContents)
- d->contentsSections = d->sectionCount;
+ d->contentsSections = newSectionCount;
if (!d->sectionHidden.isEmpty())
- d->sectionHidden.resize(d->sectionCount);
+ d->sectionHidden.resize(newSectionCount);
- if (d->sectionCount > oldCount)
+ if (newSectionCount > oldCount)
d->createSectionSpan(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode);
//Q_ASSERT(d->headerLength() == d->length);
- if (d->sectionCount != oldCount)
- emit sectionCountChanged(oldCount, d->sectionCount);
+ if (d->sectionCount() != oldCount)
+ emit sectionCountChanged(oldCount, d->sectionCount());
d->viewport->update();
}
@@ -2996,7 +2994,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
delayedResize.stop();
executePostedLayout();
- if (sectionCount == 0)
+ if (sectionCount() == 0)
return;
if (resizeRecursionBlock)
@@ -3016,7 +3014,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
int lengthToStrech = (orientation == Qt::Horizontal ? viewport->width() : viewport->height());
int numberOfStretchedSections = 0;
QList<int> section_sizes;
- for (int i = 0; i < sectionCount; ++i) {
+ for (int i = 0; i < sectionCount(); ++i) {
if (isVisualIndexHidden(i))
continue;
@@ -3060,7 +3058,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive;
// resize each section along the total length
- for (int i = 0; i < sectionCount; ++i) {
+ for (int i = 0; i < sectionCount(); ++i) {
int oldSectionLength = headerSectionSize(i);
int newSectionLength = -1;
QHeaderView::ResizeMode newSectionResizeMode = headerSectionResizeMode(i);
@@ -3107,8 +3105,8 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
previousSectionResizeMode = newSectionResizeMode;
}
- createSectionSpan(spanStartSection, sectionCount - 1,
- (sectionCount - spanStartSection) * previousSectionLength,
+ createSectionSpan(spanStartSection, sectionCount() - 1,
+ (sectionCount() - spanStartSection) * previousSectionLength,
previousSectionResizeMode);
//Q_ASSERT(headerLength() == length);
resizeRecursionBlock = false;
@@ -3144,7 +3142,6 @@ void QHeaderViewPrivate::clear()
{
if (state != NoClear) {
length = 0;
- sectionCount = 0;
visualIndices.clear();
logicalIndices.clear();
sectionSelected.clear();
@@ -3205,7 +3202,7 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
}
// cascade the section size change
- for (int i = visual + 1; i < sectionCount; ++i) {
+ for (int i = visual + 1; i < sectionCount(); ++i) {
if (!sectionIsCascadable(i))
continue;
int currentSectionSize = headerSectionSize(i);
@@ -3261,7 +3258,7 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
// let the next section get the space from the resized section
if (!sectionResized) {
- for (int i = visual + 1; i < sectionCount; ++i) {
+ for (int i = visual + 1; i < sectionCount(); ++i) {
if (!sectionIsCascadable(i))
continue;
int currentSectionSize = headerSectionSize(i);
@@ -3317,14 +3314,14 @@ void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, int oldSize, int new
int QHeaderViewPrivate::headerSectionSize(int visual) const
{
- if (visual < sectionCount && visual >= 0)
+ if (visual < sectionCount() && visual >= 0)
return sectionSpans.at(visual).sectionSize();
return -1;
}
int QHeaderViewPrivate::headerSectionPosition(int visual) const
{
- if (visual < sectionCount && visual >= 0) {
+ if (visual < sectionCount() && visual >= 0) {
if (sectionStartposRecalc)
recalcSectionStartPos();
return sectionSpans.at(visual).calculated_startpos;
@@ -3416,7 +3413,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << hiddenSectionSize;
out << length;
- out << sectionCount;
+ out << sectionCount();
out << movableSections;
out << clickableSections;
out << highlightSelected;
@@ -3452,7 +3449,8 @@ bool QHeaderViewPrivate::read(QDataStream &in)
in >> hiddenSectionSize;
in >> length;
- in >> sectionCount;
+ int unusedSectionCount; // For compability
+ in >> unusedSectionCount;
in >> movableSections;
in >> clickableSections;
in >> highlightSelected;
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index 2c657221dd..a2b0ef2180 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -84,7 +84,6 @@ public:
pressed(-1),
hover(-1),
length(0),
- sectionCount(0),
movableSections(false),
clickableSections(false),
highlightSelected(false),
@@ -137,11 +136,13 @@ public:
inline void prepareSectionSelected() {
if (!selectionModel || !selectionModel->hasSelection())
sectionSelected.clear();
- else if (sectionSelected.count() != sectionCount * 2)
- sectionSelected.fill(false, sectionCount * 2);
+ else if (sectionSelected.count() != sectionCount() * 2)
+ sectionSelected.fill(false, sectionCount() * 2);
else sectionSelected.fill(false);
}
+ inline int sectionCount() const {return sectionSpans.count();}
+
inline bool reverse() const {
return orientation == Qt::Horizontal && q_func()->isRightToLeft();
}
@@ -182,11 +183,11 @@ public:
}
inline void initializeIndexMapping() const {
- if (visualIndices.count() != sectionCount
- || logicalIndices.count() != sectionCount) {
- visualIndices.resize(sectionCount);
- logicalIndices.resize(sectionCount);
- for (int s = 0; s < sectionCount; ++s) {
+ if (visualIndices.count() != sectionCount()
+ || logicalIndices.count() != sectionCount()) {
+ visualIndices.resize(sectionCount());
+ logicalIndices.resize(sectionCount());
+ for (int s = 0; s < sectionCount(); ++s) {
visualIndices[s] = s;
logicalIndices[s] = s;
}
@@ -194,7 +195,7 @@ public:
}
inline void clearCascadingSections() {
- firstCascadingSection = sectionCount;
+ firstCascadingSection = sectionSpans.count();
lastCascadingSection = 0;
cascadingSectionSize.clear();
}
@@ -265,7 +266,6 @@ public:
int hover;
int length;
- int sectionCount;
bool movableSections;
bool clickableSections;
bool highlightSelected;
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index a5351301a7..419c62ff65 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -44,6 +44,8 @@
#ifndef QT_NO_ITEMVIEWS
#include <qabstractitemmodel.h>
#include <qapplication.h>
+#include <qplatformintegration_qpa.h>
+#include <private/qguiapplication_p.h>
#include <qbrush.h>
#include <qlineedit.h>
#include <qtextedit.h>
@@ -229,12 +231,12 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
reimplemented here:
\list
- \o createEditor() returns the widget used to change data from the model
+ \li createEditor() returns the widget used to change data from the model
and can be reimplemented to customize editing behavior.
- \o setEditorData() provides the widget with data to manipulate.
- \o updateEditorGeometry() ensures that the editor is displayed correctly
+ \li setEditorData() provides the widget with data to manipulate.
+ \li updateEditorGeometry() ensures that the editor is displayed correctly
with respect to the item view.
- \o setModelData() returns updated data to the model.
+ \li setModelData() returns updated data to the model.
\endlist
The closeEditor() signal indicates that the user has completed editing the data,
@@ -248,28 +250,28 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
appearance of the delegate as described in the following table.
\table
- \header \o Role \o Accepted Types
+ \header \li Role \li Accepted Types
\omit
- \row \o \l Qt::AccessibleDescriptionRole \o QString
- \row \o \l Qt::AccessibleTextRole \o QString
+ \row \li \l Qt::AccessibleDescriptionRole \li QString
+ \row \li \l Qt::AccessibleTextRole \li QString
\endomit
- \row \o \l Qt::BackgroundRole \o QBrush
- \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
- \row \o \l Qt::CheckStateRole \o Qt::CheckState
- \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor
- \row \o \l Qt::DisplayRole \o QString and types with a string representation
- \row \o \l Qt::EditRole \o See QItemEditorFactory for details
- \row \o \l Qt::FontRole \o QFont
- \row \o \l Qt::SizeHintRole \o QSize
+ \row \li \l Qt::BackgroundRole \li QBrush
+ \row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead)
+ \row \li \l Qt::CheckStateRole \li Qt::CheckState
+ \row \li \l Qt::DecorationRole \li QIcon, QPixmap and QColor
+ \row \li \l Qt::DisplayRole \li QString and types with a string representation
+ \row \li \l Qt::EditRole \li See QItemEditorFactory for details
+ \row \li \l Qt::FontRole \li QFont
+ \row \li \l Qt::SizeHintRole \li QSize
\omit
- \row \o \l Qt::StatusTipRole \o
+ \row \li \l Qt::StatusTipRole \li
\endomit
- \row \o \l Qt::TextAlignmentRole \o Qt::Alignment
- \row \o \l Qt::ForegroundRole \o QBrush
- \row \o \l Qt::TextColorRole \o QColor (obsolete; use Qt::ForegroundRole instead)
+ \row \li \l Qt::TextAlignmentRole \li Qt::Alignment
+ \row \li \l Qt::ForegroundRole \li QBrush
+ \row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead)
\omit
- \row \o \l Qt::ToolTipRole
- \row \o \l Qt::WhatsThisRole
+ \row \li \l Qt::ToolTipRole
+ \row \li \l Qt::WhatsThisRole
\endomit
\endtable
@@ -1150,11 +1152,11 @@ QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect,
key press events are handled by default:
\list
- \o \gui Tab
- \o \gui Backtab
- \o \gui Enter
- \o \gui Return
- \o \gui Esc
+ \li \gui Tab
+ \li \gui Backtab
+ \li \gui Enter
+ \li \gui Return
+ \li \gui Esc
\endlist
In the case of \gui Tab, \gui Backtab, \gui Enter and \gui Return
@@ -1224,8 +1226,10 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event)
#ifndef QT_NO_DRAGANDDROP
// The window may lose focus during an drag operation.
// i.e when dragging involves the taskbar on Windows.
- if (QDragManager::self() && QDragManager::self()->object != 0)
+ QPlatformDrag *platformDrag = QGuiApplicationPrivate::instance()->platformIntegration()->drag();
+ if (platformDrag && platformDrag->currentDrag()) {
return false;
+ }
#endif
emit commitData(editor);
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index 468929a554..b4180c18dd 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -102,16 +102,16 @@ public:
types and the standard editors provided.
\table
- \header \o Type \o Editor Widget
- \row \o bool \o QComboBox
- \row \o double \o QDoubleSpinBox
- \row \o int \o{1,2} QSpinBox
- \row \o unsigned int
- \row \o QDate \o QDateEdit
- \row \o QDateTime \o QDateTimeEdit
- \row \o QPixmap \o QLabel
- \row \o QString \o QLineEdit
- \row \o QTime \o QTimeEdit
+ \header \li Type \li Editor Widget
+ \row \li bool \li QComboBox
+ \row \li double \li QDoubleSpinBox
+ \row \li int \li{1,2} QSpinBox
+ \row \li unsigned int
+ \row \li QDate \li QDateEdit
+ \row \li QDateTime \li QDateTimeEdit
+ \row \li QPixmap \li QLabel
+ \row \li QString \li QLineEdit
+ \row \li QTime \li QTimeEdit
\endtable
Additional editors can be registered with the registerEditor() function.
@@ -168,7 +168,7 @@ QItemEditorFactory::~QItemEditorFactory()
/*!
Registers an item editor creator specified by \a creator for the given \a userType of data.
- \bold{Note:} The factory takes ownership of the item editor creator and will destroy
+ \b{Note:} The factory takes ownership of the item editor creator and will destroy
it if a new creator for the same type is registered later.
\sa createEditor()
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 8d069a8c7e..b00b1073a3 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -108,12 +108,12 @@ QT_BEGIN_NAMESPACE
be rendered as large or small icons depending on their iconSize().
\table 100%
- \row \o \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list view
- \o \inlineimage macintosh-listview.png Screenshot of a Macintosh style table view
- \o \inlineimage plastique-listview.png Screenshot of a Plastique style table view
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} list view.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} list view.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} list view.
+ \row \li \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list view
+ \li \inlineimage macintosh-listview.png Screenshot of a Macintosh style table view
+ \li \inlineimage plastique-listview.png Screenshot of a Plastique style table view
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} list view.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} list view.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} list view.
\endtable
\section1 Improving Performance
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index bb39546ec8..01cb7b4235 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1187,12 +1187,12 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
new current item and the item that was previously current.
\table 100%
- \row \o \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list widget
- \o \inlineimage macintosh-listview.png Screenshot of a Macintosh style table widget
- \o \inlineimage plastique-listview.png Screenshot of a Plastique style table widget
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} list widget.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} list widget.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} list widget.
+ \row \li \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list widget
+ \li \inlineimage macintosh-listview.png Screenshot of a Macintosh style table widget
+ \li \inlineimage plastique-listview.png Screenshot of a Plastique style table widget
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} list widget.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} list widget.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} list widget.
\endtable
\sa QListWidgetItem, QListView, QTreeView, {Model/View Programming},
diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index ca4c684e98..93893afaa8 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
@@ -44,6 +44,8 @@
#ifndef QT_NO_ITEMVIEWS
#include <qabstractitemmodel.h>
#include <qapplication.h>
+#include <qplatformintegration_qpa.h>
+#include <private/qguiapplication_p.h>
#include <qbrush.h>
#include <qlineedit.h>
#include <qtextedit.h>
@@ -141,28 +143,28 @@ public:
each of the roles to determine the appearance of items in views.
\table
- \header \o Role \o Accepted Types
+ \header \li Role \li Accepted Types
\omit
- \row \o \l Qt::AccessibleDescriptionRole \o QString
- \row \o \l Qt::AccessibleTextRole \o QString
+ \row \li \l Qt::AccessibleDescriptionRole \li QString
+ \row \li \l Qt::AccessibleTextRole \li QString
\endomit
- \row \o \l Qt::BackgroundRole \o QBrush
- \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
- \row \o \l Qt::CheckStateRole \o Qt::CheckState
- \row \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage and QColor
- \row \o \l Qt::DisplayRole \o QString and types with a string representation
- \row \o \l Qt::EditRole \o See QItemEditorFactory for details
- \row \o \l Qt::FontRole \o QFont
- \row \o \l Qt::SizeHintRole \o QSize
+ \row \li \l Qt::BackgroundRole \li QBrush
+ \row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead)
+ \row \li \l Qt::CheckStateRole \li Qt::CheckState
+ \row \li \l Qt::DecorationRole \li QIcon, QPixmap, QImage and QColor
+ \row \li \l Qt::DisplayRole \li QString and types with a string representation
+ \row \li \l Qt::EditRole \li See QItemEditorFactory for details
+ \row \li \l Qt::FontRole \li QFont
+ \row \li \l Qt::SizeHintRole \li QSize
\omit
- \row \o \l Qt::StatusTipRole \o
+ \row \li \l Qt::StatusTipRole \li
\endomit
- \row \o \l Qt::TextAlignmentRole \o Qt::Alignment
- \row \o \l Qt::ForegroundRole \o QBrush
- \row \o \l Qt::TextColorRole \o QColor (obsolete; use Qt::ForegroundRole instead)
+ \row \li \l Qt::TextAlignmentRole \li Qt::Alignment
+ \row \li \l Qt::ForegroundRole \li QBrush
+ \row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead)
\omit
- \row \o \l Qt::ToolTipRole
- \row \o \l Qt::WhatsThisRole
+ \row \li \l Qt::ToolTipRole
+ \row \li \l Qt::WhatsThisRole
\endomit
\endtable
@@ -209,12 +211,12 @@ public:
following virtual functions must be reimplemented:
\list
- \o createEditor() returns the widget used to change data from the model
+ \li createEditor() returns the widget used to change data from the model
and can be reimplemented to customize editing behavior.
- \o setEditorData() provides the widget with data to manipulate.
- \o updateEditorGeometry() ensures that the editor is displayed correctly
+ \li setEditorData() provides the widget with data to manipulate.
+ \li updateEditorGeometry() ensures that the editor is displayed correctly
with respect to the item view.
- \o setModelData() returns updated data to the model.
+ \li setModelData() returns updated data to the model.
\endlist
The \l{Star Delegate Example}{Star Delegate} example creates
@@ -616,11 +618,11 @@ void QStyledItemDelegate::setItemEditorFactory(QItemEditorFactory *factory)
key press events are handled by default:
\list
- \o \gui Tab
- \o \gui Backtab
- \o \gui Enter
- \o \gui Return
- \o \gui Esc
+ \li \gui Tab
+ \li \gui Backtab
+ \li \gui Enter
+ \li \gui Return
+ \li \gui Esc
\endlist
In the case of \gui Tab, \gui Backtab, \gui Enter and \gui Return
@@ -689,8 +691,10 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event)
#ifndef QT_NO_DRAGANDDROP
// The window may lose focus during an drag operation.
// i.e when dragging involves the taskbar on Windows.
- if (QDragManager::self() && QDragManager::self()->object != 0)
+ QPlatformDrag *platformDrag = QGuiApplicationPrivate::instance()->platformIntegration()->drag();
+ if (platformDrag && platformDrag->currentDrag()) {
return false;
+ }
#endif
emit commitData(editor);
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 7e6420bb53..d3bc826750 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -980,8 +980,8 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4
later retrieved with \l{QAbstractItemView::}{indexWidget()}.
\table
- \row \o \inlineimage qtableview-resized.png
- \o By default, the cells in a table do not expand to fill the available space.
+ \row \li \inlineimage qtableview-resized.png
+ \li By default, the cells in a table do not expand to fill the available space.
You can make the cells fill the available space by stretching the last
header section. Access the relevant header using horizontalHeader()
@@ -1010,12 +1010,12 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4
its appearance in other styles.
\table 100%
- \row \o \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table view
- \o \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table view
- \o \inlineimage plastique-tableview.png Screenshot of a Plastique style table view
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} table view.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} table view.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} table view.
+ \row \li \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table view
+ \li \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table view
+ \li \inlineimage plastique-tableview.png Screenshot of a Plastique style table view
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} table view.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} table view.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} table view.
\endtable
\sa QTableWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 5932f20327..7ae74640d6 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -1537,12 +1537,12 @@ QTableWidgetItem &QTableWidgetItem::operator=(const QTableWidgetItem &other)
clear() function.
\table 100%
- \row \o \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table widget
- \o \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table widget
- \o \inlineimage plastique-tableview.png Screenshot of a Plastique style table widget
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} table widget.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} table widget.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} table widget.
+ \row \li \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table widget
+ \li \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table widget
+ \li \inlineimage plastique-tableview.png Screenshot of a Plastique style table widget
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} table widget.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} table widget.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} table widget.
\endtable
\sa QTableWidgetItem, QTableView, {Model/View Programming}
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 7f5e5964ab..c54c11d0f5 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -113,29 +113,29 @@ QT_BEGIN_NAMESPACE
navigate in the view and interact with the contents of items:
\table
- \header \o Key \o Action
- \row \o Up \o Moves the cursor to the item in the same column on
+ \header \li Key \li Action
+ \row \li Up \li Moves the cursor to the item in the same column on
the previous row. If the parent of the current item has no more rows to
navigate to, the cursor moves to the relevant item in the last row
of the sibling that precedes the parent.
- \row \o Down \o Moves the cursor to the item in the same column on
+ \row \li Down \li Moves the cursor to the item in the same column on
the next row. If the parent of the current item has no more rows to
navigate to, the cursor moves to the relevant item in the first row
of the sibling that follows the parent.
- \row \o Left \o Hides the children of the current item (if present)
+ \row \li Left \li Hides the children of the current item (if present)
by collapsing a branch.
- \row \o Minus \o Same as LeftArrow.
- \row \o Right \o Reveals the children of the current item (if present)
+ \row \li Minus \li Same as LeftArrow.
+ \row \li Right \li Reveals the children of the current item (if present)
by expanding a branch.
- \row \o Plus \o Same as RightArrow.
- \row \o Asterisk \o Expands all children of the current item (if present).
- \row \o PageUp \o Moves the cursor up one page.
- \row \o PageDown \o Moves the cursor down one page.
- \row \o Home \o Moves the cursor to an item in the same column of the first
+ \row \li Plus \li Same as RightArrow.
+ \row \li Asterisk \li Expands all children of the current item (if present).
+ \row \li PageUp \li Moves the cursor up one page.
+ \row \li PageDown \li Moves the cursor down one page.
+ \row \li Home \li Moves the cursor to an item in the same column of the first
row of the first top-level item in the model.
- \row \o End \o Moves the cursor to an item in the same column of the last
+ \row \li End \li Moves the cursor to an item in the same column of the last
row of the last top-level item in the model.
- \row \o F2 \o In editable models, this opens the current item for editing.
+ \row \li F2 \li In editable models, this opens the current item for editing.
The Escape key can be used to cancel the editing process and revert
any changes to the data displayed.
\endtable
@@ -145,12 +145,12 @@ QT_BEGIN_NAMESPACE
\endomit
\table 100%
- \row \o \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree view
- \o \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree view
- \o \inlineimage plastique-treeview.png Screenshot of a Plastique style tree view
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} tree view.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} tree view.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} tree view.
+ \row \li \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree view
+ \li \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree view
+ \li \inlineimage plastique-treeview.png Screenshot of a Plastique style tree view
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} tree view.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} tree view.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} tree view.
\endtable
\section1 Improving Performance
@@ -3146,7 +3146,7 @@ void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, i
}
/** \internal
- creates and initialize the viewItem structure of the children of the element \i
+ creates and initialize the viewItem structure of the children of the element \li
set \a recursiveExpanding if the function has to expand all the children (called from expandAll)
\a afterIsUninitialized is when we recurse from layout(-1), it means all the items after 'i' are
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index cec709a816..156121a533 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -2376,12 +2376,12 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
whether sorting is enabled.
\table 100%
- \row \o \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree widget
- \o \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree widget
- \o \inlineimage plastique-treeview.png Screenshot of a Plastique style tree widget
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} tree widget.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} tree widget.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} tree widget.
+ \row \li \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree widget
+ \li \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree widget
+ \li \inlineimage plastique-treeview.png Screenshot of a Plastique style tree widget
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} tree widget.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} tree widget.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} tree widget.
\endtable
\sa QTreeWidgetItem, QTreeWidgetItemIterator, QTreeView,
@@ -3263,7 +3263,7 @@ void QTreeWidget::collapseItem(const QTreeWidgetItem *item)
/*!
Clears the tree widget by removing all of its items and selections.
- \bold{Note:} Since each item is removed from the tree widget before being
+ \b{Note:} Since each item is removed from the tree widget before being
deleted, the return value of QTreeWidgetItem::treeWidget() will be invalid
when called from an item's destructor.
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index c350223278..095b58eeaf 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -185,7 +185,7 @@ QApplicationPrivate::~QApplicationPrivate()
for QWidget-based applications. It handles widget specific initialization,
finalization, and provides session management.
- For any GUI application using Qt, there is precisely \bold one QApplication
+ For any GUI application using Qt, there is precisely \b one QApplication
object, no matter whether the application has 0, 1, 2 or more windows at
any given time. For non-QWidget based Qt applications, use QGuiApplication instead,
as it does not depend on the \l QtWidgets library.
@@ -195,41 +195,41 @@ QApplicationPrivate::~QApplicationPrivate()
QApplication's main areas of responsibility are:
\list
- \o It initializes the application with the user's desktop settings
+ \li It initializes the application with the user's desktop settings
such as palette(), font() and doubleClickInterval(). It keeps
track of these properties in case the user changes the desktop
globally, for example through some kind of control panel.
- \o It performs event handling, meaning that it receives events
+ \li It performs event handling, meaning that it receives events
from the underlying window system and dispatches them to the
relevant widgets. By using sendEvent() and postEvent() you can
send your own events to widgets.
- \o It parses common command line arguments and sets its internal
+ \li It parses common command line arguments and sets its internal
state accordingly. See the \l{QApplication::QApplication()}
{constructor documentation} below for more details.
- \o It defines the application's look and feel, which is
+ \li It defines the application's look and feel, which is
encapsulated in a QStyle object. This can be changed at runtime
with setStyle().
- \o It specifies how the application is to allocate colors. See
+ \li It specifies how the application is to allocate colors. See
setColorSpec() for details.
- \o It provides localization of strings that are visible to the
+ \li It provides localization of strings that are visible to the
user via translate().
- \o It provides some magical objects like the desktop() and the
+ \li It provides some magical objects like the desktop() and the
clipboard().
- \o It knows about the application's windows. You can ask which
+ \li It knows about the application's windows. You can ask which
widget is at a certain position using widgetAt(), get a list of
topLevelWidgets() and closeAllWindows(), etc.
- \o It manages the application's mouse cursor handling, see
+ \li It manages the application's mouse cursor handling, see
setOverrideCursor()
- \o It provides support for sophisticated \l{Session Management}
+ \li It provides support for sophisticated \l{Session Management}
{session management}. This makes it possible for applications
to terminate gracefully when the user logs out, to cancel a
shutdown process if termination isn't possible and even to
@@ -246,11 +246,11 @@ QApplicationPrivate::~QApplicationPrivate()
\table
\header
- \o{2,1} Groups of functions
+ \li{2,1} Groups of functions
\row
- \o System settings
- \o desktopSettingsAware(),
+ \li System settings
+ \li desktopSettingsAware(),
setDesktopSettingsAware(),
cursorFlashTime(),
setCursorFlashTime(),
@@ -266,8 +266,8 @@ QApplicationPrivate::~QApplicationPrivate()
fontMetrics().
\row
- \o Event handling
- \o exec(),
+ \li Event handling
+ \li exec(),
processEvents(),
exit(),
quit().
@@ -279,24 +279,24 @@ QApplicationPrivate::~QApplicationPrivate()
notify().
\row
- \o GUI Styles
- \o style(),
+ \li GUI Styles
+ \li style(),
setStyle().
\row
- \o Color usage
- \o colorSpec(),
+ \li Color usage
+ \li colorSpec(),
setColorSpec().
\row
- \o Text handling
- \o installTranslator(),
+ \li Text handling
+ \li installTranslator(),
removeTranslator()
translate().
\row
- \o Widgets
- \o allWidgets(),
+ \li Widgets
+ \li allWidgets(),
topLevelWidgets(),
desktop(),
activePopupWidget(),
@@ -307,21 +307,21 @@ QApplicationPrivate::~QApplicationPrivate()
widgetAt().
\row
- \o Advanced cursor handling
- \o overrideCursor(),
+ \li Advanced cursor handling
+ \li overrideCursor(),
setOverrideCursor(),
restoreOverrideCursor().
\row
- \o Session management
- \o isSessionRestored(),
+ \li Session management
+ \li isSessionRestored(),
sessionId(),
commitData(),
saveState().
\row
- \o Miscellaneous
- \o closeAllWindows(),
+ \li Miscellaneous
+ \li closeAllWindows(),
startingUp(),
closingDown(),
type().
@@ -534,25 +534,25 @@ void QApplicationPrivate::process_cmdline()
All Qt programs automatically support the following command line options:
\list
- \o -style= \e style, sets the application GUI style. Possible values
+ \li -style= \e style, sets the application GUI style. Possible values
are \c motif, \c windows, and \c platinum. If you compiled Qt with
additional styles or have additional styles as plugins these will
be available to the \c -style command line option.
- \o -style \e style, is the same as listed above.
- \o -stylesheet= \e stylesheet, sets the application \l styleSheet. The
+ \li -style \e style, is the same as listed above.
+ \li -stylesheet= \e stylesheet, sets the application \l styleSheet. The
value must be a path to a file that contains the Style Sheet.
\note Relative URLs in the Style Sheet file are relative to the
Style Sheet file's path.
- \o -stylesheet \e stylesheet, is the same as listed above.
- \o -session= \e session, restores the application from an earlier
+ \li -stylesheet \e stylesheet, is the same as listed above.
+ \li -session= \e session, restores the application from an earlier
\l{Session Management}{session}.
- \o -session \e session, is the same as listed above.
- \o -widgetcount, prints debug message at the end about number of
+ \li -session \e session, is the same as listed above.
+ \li -widgetcount, prints debug message at the end about number of
widgets left undestroyed and maximum number of widgets existed at
the same time
- \o -reverse, sets the application's layout direction to
+ \li -reverse, sets the application's layout direction to
Qt::RightToLeft
- \o -qmljsdebugger=, activates the QML/JS debugger with a specified port.
+ \li -qmljsdebugger=, activates the QML/JS debugger with a specified port.
The value must be of format port:1234[,block], where block is optional
and will make the application wait until a debugger connects to it.
\endlist
@@ -968,7 +968,7 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
\since 4.4
\brief defines a threshold for auto maximizing widgets
- \bold{The auto maximize threshold is only available as part of Qt for
+ \b{The auto maximize threshold is only available as part of Qt for
Windows CE.}
This property defines a threshold for the size of a window as a percentage
@@ -997,7 +997,7 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
the WA_InputMethodEnabled attribute set, and is typically used to launch
a virtual keyboard on devices which have very few or no keys.
- \bold{ The property only has an effect on platforms which use software input
+ \b{ The property only has an effect on platforms which use software input
panels, such as Windows CE.}
The default is platform dependent.
@@ -1275,21 +1275,21 @@ int QApplication::colorSpec()
The options are:
\list
- \o QApplication::NormalColor. This is the default color allocation
+ \li QApplication::NormalColor. This is the default color allocation
strategy. Use this option if your application uses buttons, menus,
texts and pixmaps with few colors. With this option, the
application uses system global colors. This works fine for most
applications under X11, but on the Windows platform, it may cause
dithering of non-standard colors.
- \o QApplication::CustomColor. Use this option if your application
+ \li QApplication::CustomColor. Use this option if your application
needs a small number of custom colors. On X11, this option is the
same as NormalColor. On Windows, Qt creates a Windows palette, and
allocates colors to it on demand.
- \o QApplication::ManyColor. Use this option if your application is
+ \li QApplication::ManyColor. Use this option if your application is
very color hungry, e.g., it requires thousands of colors. \br
Under X11 the effect is:
\list
- \o For 256-color displays which have at best a 256 color true
+ \li For 256-color displays which have at best a 256 color true
color visual, the default visual is used, and colors are
allocated from a color cube. The color cube is the 6x6x6
(216 color) "Web palette" (the red, green, and blue
@@ -1298,7 +1298,7 @@ int QApplication::colorSpec()
can be changed by the \e -ncols option. The user can force
the application to use the true color visual with the
\l{QApplication::QApplication()}{-visual} option.
- \o For 256-color displays which have a true color visual with
+ \li For 256-color displays which have a true color visual with
more than 256 colors, use that visual. Silicon Graphics X
servers this feature, for example. They provide an 8 bit
visual by default but can deliver true color when asked.
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 7a880986bf..ae4f0c2044 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -313,7 +313,7 @@ public:
QPointer<QWSManager> last_manager;
QWSServerCleaner qwsServerCleaner;
# ifndef QT_NO_DIRECTPAINTER
- QMap<WId, QDirectPainter *> *directPainters;
+ QHash<WId, QDirectPainter *> *directPainters;
# endif
QRect maxWindowRect(const QScreen *screen) const { return maxWindowRects[screen]; }
void setMaxWindowRect(const QScreen *screen, int screenNo, const QRect &rect);
@@ -393,7 +393,7 @@ public:
private:
#ifdef Q_WS_QWS
- QMap<const QScreen*, QRect> maxWindowRects;
+ QHash<const QScreen*, QRect> maxWindowRects;
#endif
static QApplicationPrivate *self;
diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp
index 4b7153715d..7ea77d211c 100644
--- a/src/widgets/kernel/qboxlayout.cpp
+++ b/src/widgets/kernel/qboxlayout.cpp
@@ -487,17 +487,17 @@ void QBoxLayoutPrivate::calcHfw(int w)
one of four functions:
\list
- \o addWidget() to add a widget to the QBoxLayout and set the
+ \li addWidget() to add a widget to the QBoxLayout and set the
widget's stretch factor. (The stretch factor is along the row of
boxes.)
- \o addSpacing() to create an empty box; this is one of the
+ \li addSpacing() to create an empty box; this is one of the
functions you use to create nice and spacious dialogs. See below
for ways to set margins.
- \o addStretch() to create an empty, stretchable box.
+ \li addStretch() to create an empty, stretchable box.
- \o addLayout() to add a box containing another QLayout to the row
+ \li addLayout() to add a box containing another QLayout to the row
and set that layout's stretch factor.
\endlist
@@ -508,10 +508,10 @@ void QBoxLayoutPrivate::calcHfw(int w)
QBoxLayout also includes two margin widths:
\list
- \o setContentsMargins() sets the width of the outer border on
+ \li setContentsMargins() sets the width of the outer border on
each side of the widget. This is the width of the reserved space
along each of the QBoxLayout's four sides.
- \o setSpacing() sets the width between neighboring boxes. (You
+ \li setSpacing() sets the width between neighboring boxes. (You
can use addSpacing() to get more space at a particular spot.)
\endlist
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index dd61528124..440f3f1dc2 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -1019,20 +1019,20 @@ QStyle* QFormLayoutPrivate::getStyle() const
provides the following advantages:
\list
- \o \bold{Adherence to the different platform's look and feel guidelines.}
+ \li \b{Adherence to the different platform's look and feel guidelines.}
For example, the
\l{Mac OS X Aqua} and KDE guidelines specify that the
labels should be right-aligned, whereas Windows and GNOME
applications normally use left-alignment.
- \o \bold{Support for wrapping long rows.}
+ \li \b{Support for wrapping long rows.}
For devices with small displays, QFormLayout can be set to
\l{WrapLongRows}{wrap long rows}, or even to
\l{WrapAllRows}{wrap all rows}.
- \o \bold{Convenient API for creating label--field pairs.}
+ \li \b{Convenient API for creating label--field pairs.}
The addRow() overload that takes a QString and a QWidget *
creates a QLabel behind the scenes and automatically set up
@@ -1049,30 +1049,30 @@ QStyle* QFormLayoutPrivate::getStyle() const
\table
\header
- \o QCommonStyle derived styles (except QPlastiqueStyle)
- \o QMacStyle
- \o QPlastiqueStyle
- \o Qt Extended styles
+ \li QCommonStyle derived styles (except QPlastiqueStyle)
+ \li QMacStyle
+ \li QPlastiqueStyle
+ \li Qt Extended styles
\row
- \o \inlineimage qformlayout-win.png
- \o \inlineimage qformlayout-mac.png
- \o \inlineimage qformlayout-kde.png
- \o \inlineimage qformlayout-qpe.png
+ \li \inlineimage qformlayout-win.png
+ \li \inlineimage qformlayout-mac.png
+ \li \inlineimage qformlayout-kde.png
+ \li \inlineimage qformlayout-qpe.png
\row
- \o Traditional style used for Windows, GNOME, and earlier
+ \li Traditional style used for Windows, GNOME, and earlier
versions of KDE. Labels are left aligned, and expanding
fields grow to fill the available space. (This normally
corresponds to what we would get using a two-column
QGridLayout.)
- \o Style based on the
+ \li Style based on the
\l{Mac OS X Aqua} guidelines. Labels are right-aligned,
the fields don't grow beyond their size hint, and the
form is horizontally centered.
- \o Recommended style for
+ \li Recommended style for
\l{KDE applications}. Similar to MacStyle, except that the form
is left-aligned and all fields grow to fill the available
space.
- \o Default style for Qt Extended styles. Labels are right-aligned,
+ \li Default style for Qt Extended styles. Labels are right-aligned,
expanding fields grow to fill the available space, and row
wrapping is enabled for long lines.
\endtable
@@ -1966,7 +1966,7 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
If the cell is already occupied, the \a widget is not inserted and an error message is
sent to the console.
- \bold{Note:} For most applications, addRow() or insertRow() should be used instead of setWidget().
+ \b{Note:} For most applications, addRow() or insertRow() should be used instead of setWidget().
\sa setLayout()
*/
@@ -1986,7 +1986,7 @@ void QFormLayout::setWidget(int row, ItemRole role, QWidget *widget)
If the cell is already occupied, the \a layout is not inserted and an error message is
sent to the console.
- \bold{Note:} For most applications, addRow() or insertRow() should be used instead of setLayout().
+ \b{Note:} For most applications, addRow() or insertRow() should be used instead of setLayout().
\sa setWidget()
*/
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 2e9edb1481..296d8d31e7 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -541,8 +541,8 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
}
void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
- QMap<QWidget *, QList<QGesture *> > *conflicts,
- QMap<QWidget *, QList<QGesture *> > *normal)
+ QHash<QWidget *, QList<QGesture *> > *conflicts,
+ QHash<QWidget *, QList<QGesture *> > *normal)
{
typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
GestureByTypes gestureByTypes;
@@ -588,7 +588,7 @@ void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
if (gestures.isEmpty())
return;
- typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
+ typedef QHash<QWidget *, QList<QGesture *> > GesturesPerWidget;
GesturesPerWidget conflictedGestures;
GesturesPerWidget normalStartedGestures;
diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h
index 68945a7b66..9f59550bb1 100644
--- a/src/widgets/kernel/qgesturemanager_p.h
+++ b/src/widgets/kernel/qgesturemanager_p.h
@@ -138,8 +138,8 @@ private:
void deliverEvents(const QSet<QGesture *> &gestures,
QSet<QGesture *> *undeliveredGestures);
void getGestureTargets(const QSet<QGesture*> &gestures,
- QMap<QWidget *, QList<QGesture *> > *conflicts,
- QMap<QWidget *, QList<QGesture *> > *normal);
+ QHash<QWidget *, QList<QGesture *> > *conflicts,
+ QHash<QWidget *, QList<QGesture *> > *normal);
void cancelGesturesForChildren(QGesture *originatingGesture);
};
diff --git a/src/widgets/kernel/qicon.cpp b/src/widgets/kernel/qicon.cpp
index 97edb4fb0f..369e26c21e 100644
--- a/src/widgets/kernel/qicon.cpp
+++ b/src/widgets/kernel/qicon.cpp
@@ -941,8 +941,8 @@ QString QIcon::themeName()
specification can be obtained here:
\list
- \o \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}
- \o \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}
+ \li \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}
+ \li \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}
\endlist
To fetch an icon from the current icon theme:
diff --git a/src/widgets/kernel/qiconengineplugin.cpp b/src/widgets/kernel/qiconengineplugin.cpp
index ced4f5dd3e..26c9e7890a 100644
--- a/src/widgets/kernel/qiconengineplugin.cpp
+++ b/src/widgets/kernel/qiconengineplugin.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
\ingroup plugins
\inmodule QtWidgets
- \bold {Use QIconEnginePluginV2 instead.}
+ \b {Use QIconEnginePluginV2 instead.}
The icon engine plugin is a simple plugin interface that makes it easy to
create custom icon engines that can be loaded dynamically into applications
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index d5d739e431..541350c35c 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -215,7 +215,7 @@ QSpacerItem *QLayoutPrivate::createSpacerItem(const QLayout *layout, int w, int
to a layout, use the addWidget() function; to add a child layout, use the
addLayout() function provided by the relevant QLayout subclass.
- \bold{Note:} The ownership of \a item is transferred to the layout, and it's
+ \b{Note:} The ownership of \a item is transferred to the layout, and it's
the layout's responsibility to delete it.
\sa addWidget(), QBoxLayout::addLayout(), QGridLayout::addLayout()
@@ -1270,7 +1270,7 @@ QRect QLayout::alignmentRect(const QRect &r) const
is the caller's responsibility to give the widget a reasonable
geometry or to put the widget back into a layout.
- \bold{Note:} The ownership of \a widget remains the same as
+ \b{Note:} The ownership of \a widget remains the same as
when it was added.
\sa removeItem(), QWidget::setGeometry(), addWidget()
diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp
index 664334d725..814b807b82 100644
--- a/src/widgets/kernel/qlayoutitem.cpp
+++ b/src/widgets/kernel/qlayoutitem.cpp
@@ -127,15 +127,15 @@ QSizePolicy::operator QVariant() const
manipulating empty space in layouts:
\table
- \header \o Class
- \o Functions
- \row \o QHBoxLayout
- \o \l{QBoxLayout::addSpacing()}{addSpacing()},
+ \header \li Class
+ \li Functions
+ \row \li QHBoxLayout
+ \li \l{QBoxLayout::addSpacing()}{addSpacing()},
\l{QBoxLayout::addStretch()}{addStretch()},
\l{QBoxLayout::insertSpacing()}{insertSpacing()},
\l{QBoxLayout::insertStretch()}{insertStretch()}
- \row \o QGridLayout
- \o \l{QGridLayout::setRowMinimumHeight()}{setRowMinimumHeight()},
+ \row \li QGridLayout
+ \li \l{QGridLayout::setRowMinimumHeight()}{setRowMinimumHeight()},
\l{QGridLayout::setRowStretch()}{setRowStretch()},
\l{QGridLayout::setColumnMinimumWidth()}{setColumnMinimumWidth()},
\l{QGridLayout::setColumnStretch()}{setColumnStretch()}
@@ -156,16 +156,16 @@ QSizePolicy::operator QVariant() const
manipulating widgets in layouts:
\table
- \header \o Class
- \o Functions
- \row \o QBoxLayout
- \o \l{QBoxLayout::addWidget()}{addWidget()},
+ \header \li Class
+ \li Functions
+ \row \li QBoxLayout
+ \li \l{QBoxLayout::addWidget()}{addWidget()},
\l{QBoxLayout::insertWidget()}{insertWidget()},
\l{QBoxLayout::setStretchFactor()}{setStretchFactor()}
- \row \o QGridLayout
- \o \l{QGridLayout::addWidget()}{addWidget()}
- \row \o QStackedLayout
- \o \l{QStackedLayout::addWidget()}{addWidget()},
+ \row \li QGridLayout
+ \li \l{QGridLayout::addWidget()}{addWidget()}
+ \row \li QStackedLayout
+ \li \l{QStackedLayout::addWidget()}{addWidget()},
\l{QStackedLayout::insertWidget()}{insertWidget()},
\l{QStackedLayout::currentWidget()}{currentWidget()},
\l{QStackedLayout::setCurrentWidget()}{setCurrentWidget()},
@@ -191,7 +191,7 @@ QSizePolicy::operator QVariant() const
/*!
Sets the alignment of this item to \a alignment.
- \bold{Note:} Item alignment is only supported by QLayoutItem subclasses
+ \b{Note:} Item alignment is only supported by QLayoutItem subclasses
where it would have a visual effect. Except for QSpacerItem, which provides
blank space for layouts, all public Qt classes that inherit QLayoutItem
support item alignment.
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 44995f0959..5eee5752cc 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -484,11 +484,11 @@ void QWidget::setAutoFillBackground(bool enabled)
Every widget's constructor accepts one or two standard arguments:
\list 1
- \i \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
+ \li \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
(the default), the new widget will be a window. If not, it will be
a child of \e parent, and be constrained by \e parent's geometry
(unless you specify Qt::Window as window flag).
- \i \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
+ \li \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
the default is suitable for almost all widgets, but to get, for
example, a window without a window system frame, you must use
special flags.
@@ -593,16 +593,16 @@ void QWidget::setAutoFillBackground(bool enabled)
starting with the most common ones:
\list
- \i paintEvent() is called whenever the widget needs to be repainted.
+ \li paintEvent() is called whenever the widget needs to be repainted.
Every widget displaying custom content must implement it. Painting
using a QPainter can only take place in a paintEvent() or a
function called by a paintEvent().
- \i resizeEvent() is called when the widget has been resized.
- \i mousePressEvent() is called when a mouse button is pressed while
+ \li resizeEvent() is called when the widget has been resized.
+ \li mousePressEvent() is called when a mouse button is pressed while
the mouse cursor is inside the widget, or when the widget has
grabbed the mouse using grabMouse(). Pressing the mouse without
releasing it is effectively the same as calling grabMouse().
- \i mouseReleaseEvent() is called when a mouse button is released. A
+ \li mouseReleaseEvent() is called when a mouse button is released. A
widget receives mouse release events when it has received the
corresponding mouse press event. This means that if the user
presses the mouse inside \e your widget, then drags the mouse
@@ -610,7 +610,7 @@ void QWidget::setAutoFillBackground(bool enabled)
receives the release event. There is one exception: if a popup menu
appears while the mouse button is held down, this popup immediately
steals the mouse events.
- \i mouseDoubleClickEvent() is called when the user double-clicks in
+ \li mouseDoubleClickEvent() is called when the user double-clicks in
the widget. If the user double-clicks, the widget receives a mouse
press event, a mouse release event and finally this event instead
of a second mouse press event. (Some mouse move events may also be
@@ -625,46 +625,46 @@ void QWidget::setAutoFillBackground(bool enabled)
handlers:
\list
- \i keyPressEvent() is called whenever a key is pressed, and again when
+ \li keyPressEvent() is called whenever a key is pressed, and again when
a key has been held down long enough for it to auto-repeat. The
\key Tab and \key Shift+Tab keys are only passed to the widget if
they are not used by the focus-change mechanisms. To force those
keys to be processed by your widget, you must reimplement
QWidget::event().
- \i focusInEvent() is called when the widget gains keyboard focus
+ \li focusInEvent() is called when the widget gains keyboard focus
(assuming you have called setFocusPolicy()). Well-behaved widgets
indicate that they own the keyboard focus in a clear but discreet
way.
- \i focusOutEvent() is called when the widget loses keyboard focus.
+ \li focusOutEvent() is called when the widget loses keyboard focus.
\endlist
You may be required to also reimplement some of the less common event
handlers:
\list
- \i mouseMoveEvent() is called whenever the mouse moves while a mouse
+ \li mouseMoveEvent() is called whenever the mouse moves while a mouse
button is held down. This can be useful during drag and drop
operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
you get mouse move events even when no buttons are held down.
(See also the \l{Drag and Drop} guide.)
- \i keyReleaseEvent() is called whenever a key is released and while it
+ \li keyReleaseEvent() is called whenever a key is released and while it
is held down (if the key is auto-repeating). In that case, the
widget will receive a pair of key release and key press event for
every repeat. The \key Tab and \key Shift+Tab keys are only passed
to the widget if they are not used by the focus-change mechanisms.
To force those keys to be processed by your widget, you must
reimplement QWidget::event().
- \i wheelEvent() is called whenever the user turns the mouse wheel
+ \li wheelEvent() is called whenever the user turns the mouse wheel
while the widget has the focus.
- \i enterEvent() is called when the mouse enters the widget's screen
+ \li enterEvent() is called when the mouse enters the widget's screen
space. (This excludes screen space owned by any of the widget's
children.)
- \i leaveEvent() is called when the mouse leaves the widget's screen
+ \li leaveEvent() is called when the mouse leaves the widget's screen
space. If the mouse enters a child widget it will not cause a
leaveEvent().
- \i moveEvent() is called when the widget has been moved relative to
+ \li moveEvent() is called when the widget has been moved relative to
its parent.
- \i closeEvent() is called when the user closes the widget (or when
+ \li closeEvent() is called when the user closes the widget (or when
close() is called).
\endlist
@@ -682,27 +682,27 @@ void QWidget::setAutoFillBackground(bool enabled)
\section1 Groups of Functions and Properties
\table
- \header \i Context \i Functions and Properties
+ \header \li Context \li Functions and Properties
- \row \i Window functions \i
+ \row \li Window functions \li
show(),
hide(),
raise(),
lower(),
close().
- \row \i Top-level windows \i
+ \row \li Top-level windows \li
\l windowModified, \l windowTitle, \l windowIcon, \l windowIconText,
\l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
\l maximized, showMaximized(), \l fullScreen, showFullScreen(),
showNormal().
- \row \i Window contents \i
+ \row \li Window contents \li
update(),
repaint(),
scroll().
- \row \i Geometry \i
+ \row \li Geometry \li
\l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
\l sizePolicy, sizeHint(), minimumSizeHint(),
updateGeometry(), layout(),
@@ -713,7 +713,7 @@ void QWidget::setAutoFillBackground(bool enabled)
\l maximumSize, \l minimumSize, \l sizeIncrement,
\l baseSize, setFixedSize()
- \row \i Mode \i
+ \row \li Mode \li
\l visible, isVisibleTo(),
\l enabled, isEnabledTo(),
\l modal,
@@ -722,7 +722,7 @@ void QWidget::setAutoFillBackground(bool enabled)
\l updatesEnabled,
visibleRegion().
- \row \i Look and feel \i
+ \row \li Look and feel \li
style(),
setStyle(),
\l styleSheet,
@@ -732,17 +732,17 @@ void QWidget::setAutoFillBackground(bool enabled)
backgroundRole(), setBackgroundRole(),
fontInfo(), fontMetrics().
- \row \i Keyboard focus functions \i
+ \row \li Keyboard focus functions \li
\l focus, \l focusPolicy,
setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
focusNextChild(), focusPreviousChild().
- \row \i Mouse and keyboard grabbing \i
+ \row \li Mouse and keyboard grabbing \li
grabMouse(), releaseMouse(),
grabKeyboard(), releaseKeyboard(),
mouseGrabber(), keyboardGrabber().
- \row \i Event handlers \i
+ \row \li Event handlers \li
event(),
mousePressEvent(),
mouseReleaseEvent(),
@@ -769,11 +769,11 @@ void QWidget::setAutoFillBackground(bool enabled)
customEvent().
changeEvent(),
- \row \i System functions \i
+ \row \li System functions \li
parentWidget(), window(), setParent(), winId(),
find(), metric().
- \row \i Interactive help \i
+ \row \li Interactive help \li
setToolTip(), setWhatsThis()
\endtable
@@ -815,15 +815,15 @@ void QWidget::setAutoFillBackground(bool enabled)
achieve different effects:
\list
- \i The left widget has no additional properties or widget attributes
+ \li The left widget has no additional properties or widget attributes
set. This default state suits most custom widgets using
transparency, are irregularly-shaped, or do not paint over their
entire area with an opaque brush.
- \i The center widget has the \l autoFillBackground property set. This
+ \li The center widget has the \l autoFillBackground property set. This
property is used with custom widgets that rely on the widget to
supply a default background, and do not paint over their entire
area with an opaque brush.
- \i The right widget has the Qt::WA_OpaquePaintEvent widget attribute
+ \li The right widget has the Qt::WA_OpaquePaintEvent widget attribute
set. This indicates that the widget will paint over its entire area
with opaque colors. The widget's area will initially be
\e{uninitialized}, represented in the diagram with a red diagonal
@@ -874,9 +874,9 @@ void QWidget::setAutoFillBackground(bool enabled)
Platform notes:
\list
- \o X11: This feature relies on the use of an X server that supports ARGB visuals
+ \li X11: This feature relies on the use of an X server that supports ARGB visuals
and a compositing window manager.
- \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
+ \li Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
for the translucency to work.
\endlist
@@ -891,14 +891,14 @@ void QWidget::setAutoFillBackground(bool enabled)
one of the following options:
\list 1
- \i Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
- \i Set the Qt::AA_NativeWindows attribute on your application. All
+ \li Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
+ \li Set the Qt::AA_NativeWindows attribute on your application. All
widgets will be native widgets.
- \i Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
+ \li Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
and all of its ancestors will become native (unless
Qt::WA_DontCreateNativeAncestors is set).
- \i Call QWidget::winId to enforce a native window (this implies 3).
- \i Set the Qt::WA_PaintOnScreen attribute to enforce a native window
+ \li Call QWidget::winId to enforce a native window (this implies 3).
+ \li Set the Qt::WA_PaintOnScreen attribute to enforce a native window
(this implies 3).
\endlist
@@ -957,17 +957,17 @@ QRegion qt_dirtyRegion(QWidget *widget)
/*
Widget state flags:
\list
- \i Qt::WA_WState_Created The widget has a valid winId().
- \i Qt::WA_WState_Visible The widget is currently visible.
- \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
+ \li Qt::WA_WState_Created The widget has a valid winId().
+ \li Qt::WA_WState_Visible The widget is currently visible.
+ \li Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
become visible unless you call show() on it. Qt::WA_WState_Hidden
implies !Qt::WA_WState_Visible.
- \i Qt::WA_WState_CompressKeys Compress keyboard events.
- \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
- \i Qt::WA_WState_InPaintEvent Currently processing a paint event.
- \i Qt::WA_WState_Reparented The widget has been reparented.
- \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
- \i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
+ \li Qt::WA_WState_CompressKeys Compress keyboard events.
+ \li Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
+ \li Qt::WA_WState_InPaintEvent Currently processing a paint event.
+ \li Qt::WA_WState_Reparented The widget has been reparented.
+ \li Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
+ \li Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
\endlist
*/
@@ -5689,16 +5689,16 @@ QString QWidget::windowIconText() const
On Mac OS X:
\list
- \o The file name of the specified path, obtained using QFileInfo::fileName().
+ \li The file name of the specified path, obtained using QFileInfo::fileName().
\endlist
On Windows and X11:
\list
- \o The file name of the specified path, obtained using QFileInfo::fileName().
- \o An optional \c{*} character, if the \l windowModified property is set.
- \o The \c{0x2014} unicode character, padded either side by spaces.
- \o The application name, obtained from the application's
+ \li The file name of the specified path, obtained using QFileInfo::fileName().
+ \li An optional \c{*} character, if the \l windowModified property is set.
+ \li The \c{0x2014} unicode character, padded either side by spaces.
+ \li The application name, obtained from the application's
\l{QCoreApplication::}{applicationName} property.
\endlist
@@ -7164,9 +7164,9 @@ void QWidgetPrivate::hide_helper()
Widgets are hidden if:
\list
- \o they were created as independent windows,
- \o they were created as children of visible widgets,
- \o hide() or setVisible(false) was called.
+ \li they were created as independent windows,
+ \li they were created as children of visible widgets,
+ \li hide() or setVisible(false) was called.
\endlist
*/
@@ -8587,9 +8587,9 @@ void QWidget::leaveEvent(QEvent *)
happen for one of the following reasons:
\list
- \o repaint() or update() was invoked,
- \o the widget was obscured and has now been uncovered, or
- \o many other reasons.
+ \li repaint() or update() was invoked,
+ \li the widget was obscured and has now been uncovered, or
+ \li many other reasons.
\endlist
Many widgets can simply repaint their entire surface when asked to, but
@@ -8612,13 +8612,13 @@ void QWidget::leaveEvent(QEvent *)
Since Qt 4.0, QWidget automatically double-buffers its painting, so there
is no need to write double-buffering code in paintEvent() to avoid flicker.
- \bold{Note for the X11 platform}: It is possible to toggle global double
+ \b{Note for the X11 platform}: It is possible to toggle global double
buffering by calling \c qt_x11_set_global_double_buffer(). For example,
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 14
\note Generally, you should refrain from calling update() or repaint()
- \bold{inside} a paintEvent(). For example, calling update() or repaint() on
+ \b{inside} a paintEvent(). For example, calling update() or repaint() on
children inside a paintevent() results in undefined behavior; the child may
or may not get a paint event.
@@ -8960,8 +8960,8 @@ void QWidget::hideEvent(QHideEvent *)
x11Event(), winEvent() and macEvent() of Qt 4.
\table
- \header \i Platform \i Event Type Identifier \i Message Type \i Result Type
- \row \i Windows \i "windows_generic_MSG" \i MSG * \i LRESULT
+ \header \li Platform \li Event Type Identifier \li Message Type \li Result Type
+ \row \li Windows \li "windows_generic_MSG" \li MSG * \li LRESULT
\endtable
*/
@@ -8991,7 +8991,7 @@ bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *resu
If you need to change some settings when a widget is polished,
reimplement event() and handle the QEvent::Polish event type.
- \bold{Note:} The function is declared const so that it can be called from
+ \b{Note:} The function is declared const so that it can be called from
other const functions (e.g., sizeHint()).
\sa event()
@@ -11081,7 +11081,7 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\note Only visible widgets can grab mouse input. If isVisible()
returns false for a widget, that widget cannot call grabMouse().
- \note \bold{(Mac OS X developers)} For \e Cocoa, calling
+ \note \b{(Mac OS X developers)} For \e Cocoa, calling
grabMouse() on a widget only works when the mouse is inside the
frame of that widget. For \e Carbon, it works outside the widget's
frame as well, like for Windows and X11.
@@ -11101,7 +11101,7 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\warning Grabbing the mouse might lock the terminal.
- \note \bold{(Mac OS X developers)} See the note in QWidget::grabMouse().
+ \note \b{(Mac OS X developers)} See the note in QWidget::grabMouse().
\sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
*/
diff --git a/src/widgets/kernel/qwidgetaction.cpp b/src/widgets/kernel/qwidgetaction.cpp
index 14369513da..c3fc6c7cfb 100644
--- a/src/widgets/kernel/qwidgetaction.cpp
+++ b/src/widgets/kernel/qwidgetaction.cpp
@@ -87,17 +87,17 @@ QT_BEGIN_NAMESPACE
Note that it is up to the widget to activate the action, for example by
reimplementing mouse event handlers and calling QAction::trigger().
- \bold {Mac OS X}: If you add a widget to a menu in the application's menu
+ \b {Mac OS X}: If you add a widget to a menu in the application's menu
bar on Mac OS X, the widget will be added and it will function but with some
limitations:
\list 1
- \o The widget is reparented away from the QMenu to the native menu
+ \li The widget is reparented away from the QMenu to the native menu
view. If you show the menu in some other place (e.g. as a popup menu),
the widget will not be there.
- \o Focus/Keyboard handling of the widget is not possible.
- \o Due to Apple's design, mouse tracking on the widget currently does
+ \li Focus/Keyboard handling of the widget is not possible.
+ \li Due to Apple's design, mouse tracking on the widget currently does
not work.
- \o Connecting the triggered() signal to a slot that opens a modal
+ \li Connecting the triggered() signal to a slot that opens a modal
dialog will cause a crash in Mac OS X 10.4 (known bug acknowledged
by Apple), a workaround is to use a QueuedConnection instead of a
DirectConnection.
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 18e120a4eb..0402859e31 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -897,7 +897,7 @@ extern QStringList qt_make_filter_list(const QString &filter);
void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
const QString &dir, const QString &filter, QString *selectedFilter,
QFileDialog::Options options, bool isSaveDialog,
- QMap<GtkFileFilter *, QString> *filterMap)
+ QHash<GtkFileFilter *, QString> *filterMap)
{
g_object_set(gtkFileChooser, "do-overwrite-confirmation", gboolean(!(options & QFileDialog::DontConfirmOverwrite)), NULL);
g_object_set(gtkFileChooser, "local_only", gboolean(true), NULL);
@@ -969,7 +969,7 @@ void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *p
QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options)
{
- QMap<GtkFileFilter *, QString> filterMap;
+ QHash<GtkFileFilter *, QString> filterMap;
GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -1003,7 +1003,7 @@ QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption,
QString QGtkStylePrivate::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
{
- QMap<GtkFileFilter *, QString> filterMap;
+ QHash<GtkFileFilter *, QString> filterMap;
GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
NULL,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
@@ -1033,7 +1033,7 @@ QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &capt
QString *selectedFilter, QFileDialog::Options options)
{
QStringList filenames;
- QMap<GtkFileFilter *, QString> filterMap;
+ QHash<GtkFileFilter *, QString> filterMap;
GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -1068,7 +1068,7 @@ QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &capt
QString QGtkStylePrivate::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options)
{
- QMap<GtkFileFilter *, QString> filterMap;
+ QHash<GtkFileFilter *, QString> filterMap;
GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
diff --git a/src/widgets/styles/qgtkstyle_p.h b/src/widgets/styles/qgtkstyle_p.h
index 95988fa8b1..02d659c1e4 100644
--- a/src/widgets/styles/qgtkstyle_p.h
+++ b/src/widgets/styles/qgtkstyle_p.h
@@ -344,7 +344,7 @@ public:
static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
const QString &dir, const QString &filter, QString *selectedFilter,
QFileDialog::Options options, bool isSaveDialog = false,
- QMap<GtkFileFilter *, QString> *filterMap = 0);
+ QHash<GtkFileFilter *, QString> *filterMap = 0);
static QString openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options);
diff --git a/src/widgets/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc
index d48a65c41f..dc8da491bf 100644
--- a/src/widgets/styles/qmacstyle.qdoc
+++ b/src/widgets/styles/qmacstyle.qdoc
@@ -49,21 +49,21 @@
\list
- \i Layout - The restrictions on window layout are such that some
+ \li Layout - The restrictions on window layout are such that some
aspects of layout that are style-dependent cannot be achieved
using QLayout. Changes are being considered (and feedback would be
appreciated) to make layouts QStyle-able. Some of the restrictions
involve horizontal and vertical widget alignment and widget size
(covered below).
- \i Widget size - Mac OS X allows widgets to have specific fixed sizes. Qt
+ \li Widget size - Mac OS X allows widgets to have specific fixed sizes. Qt
does not fully implement this behavior so as to maintain cross-platform
compatibility. As a result some widgets sizes may be inappropriate (and
subsequently not rendered correctly by the HITheme APIs).The
QWidget::sizeHint() will return the appropriate size for many
managed widgets (widgets enumerated in \l QStyle::ContentsType).
- \i Effects - QMacStyle uses HITheme for performing most of the drawing, but
+ \li Effects - QMacStyle uses HITheme for performing most of the drawing, but
also uses emulation in a few cases where HITheme does not provide the
required functionality (for example, tab bars on Panther, the toolbar
separator, etc). We tried to make the emulation as close to the original as
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 3ff5aea0ca..db387fecec 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -124,10 +124,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
Most QStyle draw functions take four arguments:
\list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption specifying how and where to render that element
- \o a QPainter that should be used to draw the element
- \o a QWidget on which the drawing is performed (optional)
+ \li an enum value specifying which graphical element to draw
+ \li a QStyleOption specifying how and where to render that element
+ \li a QPainter that should be used to draw the element
+ \li a QWidget on which the drawing is performed (optional)
\endlist
For example, if you want to draw a focus rectangle on your
@@ -275,12 +275,12 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
right-to-left environment:
\list
- \o subControlRect() and subElementRect() return rectangles in screen coordinates
- \o QStyleOption::direction indicates in which direction the item should be drawn in
- \o If a style is not right-to-left aware it will display items as if it were left-to-right
- \o visualRect(), visualPos(), and visualAlignment() are helpful functions that will
+ \li subControlRect() and subElementRect() return rectangles in screen coordinates
+ \li QStyleOption::direction indicates in which direction the item should be drawn in
+ \li If a style is not right-to-left aware it will display items as if it were left-to-right
+ \li visualRect(), visualPos(), and visualAlignment() are helpful functions that will
translate from logical to screen representations.
- \o alignedRect() will return a logical rect aligned for the current direction
+ \li alignedRect() will return a logical rect aligned for the current direction
\endlist
\section1 Styles in Item Views
@@ -731,50 +731,50 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
it uses a plain QStyleOption object.
\table
- \header \o Primitive Element \o QStyleOption Subclass \o Style Flag \o Remark
- \row \o \l PE_FrameFocusRect \o \l QStyleOptionFocusRect
- \o \l State_FocusAtBorder
- \o Whether the focus is is at the border or inside the widget.
- \row \o{1,2} \l PE_IndicatorCheckBox \o{1,2} \l QStyleOptionButton
- \o \l State_NoChange \o Indicates a "tri-state" checkbox.
- \row \o \l State_On \o Indicates the indicator is checked.
- \row \o \l PE_IndicatorRadioButton \o \l QStyleOptionButton
- \o \l State_On \o Indicates that a radio button is selected.
- \row \o{1,3} \l PE_Q3CheckListExclusiveIndicator, \l PE_Q3CheckListIndicator
- \o{1,3} \l QStyleOptionQ3ListView \o \l State_On
- \o Indicates whether or not the controller is selected.
- \row \o \l State_NoChange \o Indicates a "tri-state" controller.
- \row \o \l State_Enabled \o Indicates the controller is enabled.
- \row \o{1,4} \l PE_IndicatorBranch \o{1,4} \l QStyleOption
- \o \l State_Children \o Indicates that the control for expanding the tree to show child items, should be drawn.
- \row \o \l State_Item \o Indicates that a horizontal branch (to show a child item), should be drawn.
- \row \o \l State_Open \o Indicates that the tree branch is expanded.
- \row \o \l State_Sibling \o Indicates that a vertical line (to show a sibling item), should be drawn.
- \row \o \l PE_IndicatorHeaderArrow \o \l QStyleOptionHeader
- \o \l State_UpArrow \o Indicates that the arrow should be drawn up;
+ \header \li Primitive Element \li QStyleOption Subclass \li Style Flag \li Remark
+ \row \li \l PE_FrameFocusRect \li \l QStyleOptionFocusRect
+ \li \l State_FocusAtBorder
+ \li Whether the focus is is at the border or inside the widget.
+ \row \li{1,2} \l PE_IndicatorCheckBox \li{1,2} \l QStyleOptionButton
+ \li \l State_NoChange \li Indicates a "tri-state" checkbox.
+ \row \li \l State_On \li Indicates the indicator is checked.
+ \row \li \l PE_IndicatorRadioButton \li \l QStyleOptionButton
+ \li \l State_On \li Indicates that a radio button is selected.
+ \row \li{1,3} \l PE_Q3CheckListExclusiveIndicator, \l PE_Q3CheckListIndicator
+ \li{1,3} \l QStyleOptionQ3ListView \li \l State_On
+ \li Indicates whether or not the controller is selected.
+ \row \li \l State_NoChange \li Indicates a "tri-state" controller.
+ \row \li \l State_Enabled \li Indicates the controller is enabled.
+ \row \li{1,4} \l PE_IndicatorBranch \li{1,4} \l QStyleOption
+ \li \l State_Children \li Indicates that the control for expanding the tree to show child items, should be drawn.
+ \row \li \l State_Item \li Indicates that a horizontal branch (to show a child item), should be drawn.
+ \row \li \l State_Open \li Indicates that the tree branch is expanded.
+ \row \li \l State_Sibling \li Indicates that a vertical line (to show a sibling item), should be drawn.
+ \row \li \l PE_IndicatorHeaderArrow \li \l QStyleOptionHeader
+ \li \l State_UpArrow \li Indicates that the arrow should be drawn up;
otherwise it should be down.
- \row \o \l PE_FrameGroupBox, \l PE_Frame, \l PE_FrameLineEdit,
+ \row \li \l PE_FrameGroupBox, \l PE_Frame, \l PE_FrameLineEdit,
\l PE_FrameMenu, \l PE_FrameDockWidget, \l PE_FrameWindow
- \o \l QStyleOptionFrame \o \l State_Sunken
- \o Indicates that the Frame should be sunken.
- \row \o \l PE_IndicatorToolBarHandle \o \l QStyleOption
- \o \l State_Horizontal \o Indicates that the window handle is horizontal
+ \li \l QStyleOptionFrame \li \l State_Sunken
+ \li Indicates that the Frame should be sunken.
+ \row \li \l PE_IndicatorToolBarHandle \li \l QStyleOption
+ \li \l State_Horizontal \li Indicates that the window handle is horizontal
instead of vertical.
- \row \o \l PE_Q3DockWindowSeparator \o \l QStyleOption
- \o \l State_Horizontal \o Indicates that the separator is horizontal
+ \row \li \l PE_Q3DockWindowSeparator \li \l QStyleOption
+ \li \l State_Horizontal \li Indicates that the separator is horizontal
instead of vertical.
- \row \o \l PE_IndicatorSpinPlus, \l PE_IndicatorSpinMinus, \l PE_IndicatorSpinUp,
+ \row \li \l PE_IndicatorSpinPlus, \l PE_IndicatorSpinMinus, \l PE_IndicatorSpinUp,
\l PE_IndicatorSpinDown,
- \o \l QStyleOptionSpinBox
- \o \l State_Sunken \o Indicates that the button is pressed.
- \row \o{1,5} \l PE_PanelButtonCommand
- \o{1,5} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
- \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or the
+ \li \l QStyleOptionSpinBox
+ \li \l State_Sunken \li Indicates that the button is pressed.
+ \row \li{1,5} \l PE_PanelButtonCommand
+ \li{1,5} \l QStyleOptionButton
+ \li \l State_Enabled \li Set if the button is enabled.
+ \row \li \l State_HasFocus \li Set if the button has input focus.
+ \row \li \l State_Raised \li Set if the button is not down, not on and not flat.
+ \row \li \l State_On \li Set if the button is a toggle button and is toggled on.
+ \row \li \l State_Sunken
+ \li Set if the button is down (i.e., the mouse button or the
space bar is pressed on the button).
\endtable
@@ -887,69 +887,69 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
it uses a plain QStyleOption object.
\table
- \header \o Control Element \o QStyleOption Subclass \o Style Flag \o Remark
- \row \o{1,5} \l CE_MenuItem, \l CE_MenuBarItem
- \o{1,5} \l QStyleOptionMenuItem
- \o \l State_Selected \o The menu item is currently selected item.
- \row \o \l State_Enabled \o The item is enabled.
- \row \o \l State_DownArrow \o Indicates that a scroll down arrow should be drawn.
- \row \o \l State_UpArrow \o Indicates that a scroll up arrow should be drawn
- \row \o \l State_HasFocus \o Set if the menu bar has input focus.
-
- \row \o{1,5} \l CE_PushButton, \l CE_PushButtonBevel, \l CE_PushButtonLabel
- \o{1,5} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
- \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or the
+ \header \li Control Element \li QStyleOption Subclass \li Style Flag \li Remark
+ \row \li{1,5} \l CE_MenuItem, \l CE_MenuBarItem
+ \li{1,5} \l QStyleOptionMenuItem
+ \li \l State_Selected \li The menu item is currently selected item.
+ \row \li \l State_Enabled \li The item is enabled.
+ \row \li \l State_DownArrow \li Indicates that a scroll down arrow should be drawn.
+ \row \li \l State_UpArrow \li Indicates that a scroll up arrow should be drawn
+ \row \li \l State_HasFocus \li Set if the menu bar has input focus.
+
+ \row \li{1,5} \l CE_PushButton, \l CE_PushButtonBevel, \l CE_PushButtonLabel
+ \li{1,5} \l QStyleOptionButton
+ \li \l State_Enabled \li Set if the button is enabled.
+ \row \li \l State_HasFocus \li Set if the button has input focus.
+ \row \li \l State_Raised \li Set if the button is not down, not on and not flat.
+ \row \li \l State_On \li Set if the button is a toggle button and is toggled on.
+ \row \li \l State_Sunken
+ \li Set if the button is down (i.e., the mouse button or the
space bar is pressed on the button).
- \row \o{1,6} \l CE_RadioButton, \l CE_RadioButtonLabel,
+ \row \li{1,6} \l CE_RadioButton, \l CE_RadioButtonLabel,
\l CE_CheckBox, \l CE_CheckBoxLabel
- \o{1,6} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_On \o Set if the button is checked.
- \row \o \l State_Off \o Set if the button is not checked.
- \row \o \l State_NoChange \o Set if the button is in the NoChange state.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or
+ \li{1,6} \l QStyleOptionButton
+ \li \l State_Enabled \li Set if the button is enabled.
+ \row \li \l State_HasFocus \li Set if the button has input focus.
+ \row \li \l State_On \li Set if the button is checked.
+ \row \li \l State_Off \li Set if the button is not checked.
+ \row \li \l State_NoChange \li Set if the button is in the NoChange state.
+ \row \li \l State_Sunken
+ \li Set if the button is down (i.e., the mouse button or
the space bar is pressed on the button).
- \row \o{1,2} \l CE_ProgressBarContents, \l CE_ProgressBarLabel,
+ \row \li{1,2} \l CE_ProgressBarContents, \l CE_ProgressBarLabel,
\l CE_ProgressBarGroove
- \o{1,2} \l QStyleOptionProgressBar
- \o \l State_Enabled \o Set if the progress bar is enabled.
- \row \o \l State_HasFocus \o Set if the progress bar has input focus.
-
- \row \o \l CE_Header, \l CE_HeaderSection, \l CE_HeaderLabel \o \l QStyleOptionHeader \o \o
-
- \row \o{1,3} \l CE_TabBarTab, CE_TabBarTabShape, CE_TabBarTabLabel
- \o{1,3} \l QStyleOptionTab
- \o \l State_Enabled \o Set if the tab bar is enabled.
- \row \o \l State_Selected \o The tab bar is the currently selected tab bar.
- \row \o \l State_HasFocus \o Set if the tab bar tab has input focus.
-
- \row \o{1,7} \l CE_ToolButtonLabel
- \o{1,7} \l QStyleOptionToolButton
- \o \l State_Enabled \o Set if the tool button is enabled.
- \row \o \l State_HasFocus \o Set if the tool button has input focus.
- \row \o \l State_Sunken
- \o Set if the tool button is down (i.e., a mouse button or
+ \li{1,2} \l QStyleOptionProgressBar
+ \li \l State_Enabled \li Set if the progress bar is enabled.
+ \row \li \l State_HasFocus \li Set if the progress bar has input focus.
+
+ \row \li \l CE_Header, \l CE_HeaderSection, \l CE_HeaderLabel \li \l QStyleOptionHeader \li \li
+
+ \row \li{1,3} \l CE_TabBarTab, CE_TabBarTabShape, CE_TabBarTabLabel
+ \li{1,3} \l QStyleOptionTab
+ \li \l State_Enabled \li Set if the tab bar is enabled.
+ \row \li \l State_Selected \li The tab bar is the currently selected tab bar.
+ \row \li \l State_HasFocus \li Set if the tab bar tab has input focus.
+
+ \row \li{1,7} \l CE_ToolButtonLabel
+ \li{1,7} \l QStyleOptionToolButton
+ \li \l State_Enabled \li Set if the tool button is enabled.
+ \row \li \l State_HasFocus \li Set if the tool button has input focus.
+ \row \li \l State_Sunken
+ \li Set if the tool button is down (i.e., a mouse button or
the space bar is pressed).
- \row \o \l State_On \o Set if the tool button is a toggle button and is toggled on.
- \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
- \row \o \l State_MouseOver \o Set if the mouse pointer is over the tool button.
- \row \o \l State_Raised \o Set if the button is not down and is not on.
-
- \row \o \l CE_ToolBoxTab \o \l QStyleOptionToolBox
- \o \l State_Selected \o The tab is the currently selected tab.
- \row \o{1,3} \l CE_HeaderSection \o{1,3} \l QStyleOptionHeader
- \o \l State_Sunken \o Indicates that the section is pressed.
- \row \o \l State_UpArrow \o Indicates that the sort indicator should be pointing up.
- \row \o \l State_DownArrow \o Indicates that the sort indicator should be pointing down.
+ \row \li \l State_On \li Set if the tool button is a toggle button and is toggled on.
+ \row \li \l State_AutoRaise \li Set if the tool button has auto-raise enabled.
+ \row \li \l State_MouseOver \li Set if the mouse pointer is over the tool button.
+ \row \li \l State_Raised \li Set if the button is not down and is not on.
+
+ \row \li \l CE_ToolBoxTab \li \l QStyleOptionToolBox
+ \li \l State_Selected \li The tab is the currently selected tab.
+ \row \li{1,3} \l CE_HeaderSection \li{1,3} \l QStyleOptionHeader
+ \li \l State_Sunken \li Indicates that the section is pressed.
+ \row \li \l State_UpArrow \li Indicates that the sort indicator should be pointing up.
+ \row \li \l State_DownArrow \li Indicates that the sort indicator should be pointing down.
\endtable
\sa drawPrimitive(), drawComplexControl()
@@ -1077,20 +1077,20 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
table below for the appropriate \a option casts:
\table
- \header \o Sub Element \o QStyleOption Subclass
- \row \o \l SE_PushButtonContents \o \l QStyleOptionButton
- \row \o \l SE_PushButtonFocusRect \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxIndicator \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxContents \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxFocusRect \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonIndicator \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonContents \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonFocusRect \o \l QStyleOptionButton
- \row \o \l SE_ComboBoxFocusRect \o \l QStyleOptionComboBox
- \row \o \l SE_Q3DockWindowHandleRect \o \l QStyleOptionQ3DockWindow
- \row \o \l SE_ProgressBarGroove \o \l QStyleOptionProgressBar
- \row \o \l SE_ProgressBarContents \o \l QStyleOptionProgressBar
- \row \o \l SE_ProgressBarLabel \o \l QStyleOptionProgressBar
+ \header \li Sub Element \li QStyleOption Subclass
+ \row \li \l SE_PushButtonContents \li \l QStyleOptionButton
+ \row \li \l SE_PushButtonFocusRect \li \l QStyleOptionButton
+ \row \li \l SE_CheckBoxIndicator \li \l QStyleOptionButton
+ \row \li \l SE_CheckBoxContents \li \l QStyleOptionButton
+ \row \li \l SE_CheckBoxFocusRect \li \l QStyleOptionButton
+ \row \li \l SE_RadioButtonIndicator \li \l QStyleOptionButton
+ \row \li \l SE_RadioButtonContents \li \l QStyleOptionButton
+ \row \li \l SE_RadioButtonFocusRect \li \l QStyleOptionButton
+ \row \li \l SE_ComboBoxFocusRect \li \l QStyleOptionComboBox
+ \row \li \l SE_Q3DockWindowHandleRect \li \l QStyleOptionQ3DockWindow
+ \row \li \l SE_ProgressBarGroove \li \l QStyleOptionProgressBar
+ \row \li \l SE_ProgressBarContents \li \l QStyleOptionProgressBar
+ \row \li \l SE_ProgressBarLabel \li \l QStyleOptionProgressBar
\endtable
*/
@@ -1222,43 +1222,43 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
appropriate subclass.
\table
- \header \o Complex Control \o QStyleOptionComplex Subclass \o Style Flag \o Remark
- \row \o{1,2} \l{CC_SpinBox} \o{1,2} \l QStyleOptionSpinBox
- \o \l State_Enabled \o Set if the spin box is enabled.
- \row \o \l State_HasFocus \o Set if the spin box has input focus.
-
- \row \o{1,2} \l {CC_ComboBox} \o{1,2} \l QStyleOptionComboBox
- \o \l State_Enabled \o Set if the combobox is enabled.
- \row \o \l State_HasFocus \o Set if the combobox has input focus.
-
- \row \o{1,2} \l {CC_ScrollBar} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the scroll bar is enabled.
- \row \o \l State_HasFocus \o Set if the scroll bar has input focus.
-
- \row \o{1,2} \l {CC_Slider} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the slider is enabled.
- \row \o \l State_HasFocus \o Set if the slider has input focus.
-
- \row \o{1,2} \l {CC_Dial} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the dial is enabled.
- \row \o \l State_HasFocus \o Set if the dial has input focus.
-
- \row \o{1,6} \l {CC_ToolButton} \o{1,6} \l QStyleOptionToolButton
- \o \l State_Enabled \o Set if the tool button is enabled.
- \row \o \l State_HasFocus \o Set if the tool button has input focus.
- \row \o \l State_DownArrow \o Set if the tool button is down (i.e., a mouse
+ \header \li Complex Control \li QStyleOptionComplex Subclass \li Style Flag \li Remark
+ \row \li{1,2} \l{CC_SpinBox} \li{1,2} \l QStyleOptionSpinBox
+ \li \l State_Enabled \li Set if the spin box is enabled.
+ \row \li \l State_HasFocus \li Set if the spin box has input focus.
+
+ \row \li{1,2} \l {CC_ComboBox} \li{1,2} \l QStyleOptionComboBox
+ \li \l State_Enabled \li Set if the combobox is enabled.
+ \row \li \l State_HasFocus \li Set if the combobox has input focus.
+
+ \row \li{1,2} \l {CC_ScrollBar} \li{1,2} \l QStyleOptionSlider
+ \li \l State_Enabled \li Set if the scroll bar is enabled.
+ \row \li \l State_HasFocus \li Set if the scroll bar has input focus.
+
+ \row \li{1,2} \l {CC_Slider} \li{1,2} \l QStyleOptionSlider
+ \li \l State_Enabled \li Set if the slider is enabled.
+ \row \li \l State_HasFocus \li Set if the slider has input focus.
+
+ \row \li{1,2} \l {CC_Dial} \li{1,2} \l QStyleOptionSlider
+ \li \l State_Enabled \li Set if the dial is enabled.
+ \row \li \l State_HasFocus \li Set if the dial has input focus.
+
+ \row \li{1,6} \l {CC_ToolButton} \li{1,6} \l QStyleOptionToolButton
+ \li \l State_Enabled \li Set if the tool button is enabled.
+ \row \li \l State_HasFocus \li Set if the tool button has input focus.
+ \row \li \l State_DownArrow \li Set if the tool button is down (i.e., a mouse
button or the space bar is pressed).
- \row \o \l State_On \o Set if the tool button is a toggle button
+ \row \li \l State_On \li Set if the tool button is a toggle button
and is toggled on.
- \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
- \row \o \l State_Raised \o Set if the button is not down, not on, and doesn't
+ \row \li \l State_AutoRaise \li Set if the tool button has auto-raise enabled.
+ \row \li \l State_Raised \li Set if the button is not down, not on, and doesn't
contain the mouse when auto-raise is enabled.
- \row \o \l{CC_TitleBar} \o \l QStyleOptionTitleBar
- \o \l State_Enabled \o Set if the title bar is enabled.
+ \row \li \l{CC_TitleBar} \li \l QStyleOptionTitleBar
+ \li \l State_Enabled \li Set if the title bar is enabled.
- \row \o \l{CC_Q3ListView} \o \l QStyleOptionQ3ListView
- \o \l State_Enabled \o Set if the list view is enabled.
+ \row \li \l{CC_Q3ListView} \li \l QStyleOptionQ3ListView
+ \li \l State_Enabled \li Set if the list view is enabled.
\endtable
@@ -1492,17 +1492,17 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
for the appropriate \a option casts:
\table
- \header \o Pixel Metric \o QStyleOption Subclass
- \row \o \l PM_SliderControlThickness \o \l QStyleOptionSlider
- \row \o \l PM_SliderLength \o \l QStyleOptionSlider
- \row \o \l PM_SliderTickmarkOffset \o \l QStyleOptionSlider
- \row \o \l PM_SliderSpaceAvailable \o \l QStyleOptionSlider
- \row \o \l PM_ScrollBarExtent \o \l QStyleOptionSlider
- \row \o \l PM_TabBarTabOverlap \o \l QStyleOptionTab
- \row \o \l PM_TabBarTabHSpace \o \l QStyleOptionTab
- \row \o \l PM_TabBarTabVSpace \o \l QStyleOptionTab
- \row \o \l PM_TabBarBaseHeight \o \l QStyleOptionTab
- \row \o \l PM_TabBarBaseOverlap \o \l QStyleOptionTab
+ \header \li Pixel Metric \li QStyleOption Subclass
+ \row \li \l PM_SliderControlThickness \li \l QStyleOptionSlider
+ \row \li \l PM_SliderLength \li \l QStyleOptionSlider
+ \row \li \l PM_SliderTickmarkOffset \li \l QStyleOptionSlider
+ \row \li \l PM_SliderSpaceAvailable \li \l QStyleOptionSlider
+ \row \li \l PM_ScrollBarExtent \li \l QStyleOptionSlider
+ \row \li \l PM_TabBarTabOverlap \li \l QStyleOptionTab
+ \row \li \l PM_TabBarTabHSpace \li \l QStyleOptionTab
+ \row \li \l PM_TabBarTabVSpace \li \l QStyleOptionTab
+ \row \li \l PM_TabBarBaseHeight \li \l QStyleOptionTab
+ \row \li \l PM_TabBarBaseOverlap \li \l QStyleOptionTab
\endtable
Some pixel metrics are called from widgets and some are only called
@@ -1568,16 +1568,16 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
See the table below for the appropriate \a option casts:
\table
- \header \o Contents Type \o QStyleOption Subclass
- \row \o \l CT_PushButton \o \l QStyleOptionButton
- \row \o \l CT_CheckBox \o \l QStyleOptionButton
- \row \o \l CT_RadioButton \o \l QStyleOptionButton
- \row \o \l CT_ToolButton \o \l QStyleOptionToolButton
- \row \o \l CT_ComboBox \o \l QStyleOptionComboBox
- \row \o \l CT_Splitter \o \l QStyleOption
- \row \o \l CT_Q3DockWindow \o \l QStyleOptionQ3DockWindow
- \row \o \l CT_ProgressBar \o \l QStyleOptionProgressBar
- \row \o \l CT_MenuItem \o \l QStyleOptionMenuItem
+ \header \li Contents Type \li QStyleOption Subclass
+ \row \li \l CT_PushButton \li \l QStyleOptionButton
+ \row \li \l CT_CheckBox \li \l QStyleOptionButton
+ \row \li \l CT_RadioButton \li \l QStyleOptionButton
+ \row \li \l CT_ToolButton \li \l QStyleOptionToolButton
+ \row \li \l CT_ComboBox \li \l QStyleOptionComboBox
+ \row \li \l CT_Splitter \li \l QStyleOption
+ \row \li \l CT_Q3DockWindow \li \l QStyleOptionQ3DockWindow
+ \row \li \l CT_ProgressBar \li \l QStyleOptionProgressBar
+ \row \li \l CT_MenuItem \li \l QStyleOptionMenuItem
\endtable
\sa ContentsType QStyleOption
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 63e7b8775e..d72ba1bac5 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1795,7 +1795,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
\brief the text for the menu item
Note that the text format is something like this "Menu
- text\bold{\\t}Shortcut".
+ text\b{\\t}Shortcut".
If the menu item doesn't have a shortcut, it will just contain the
menu item's text. The default value is an empty string.
@@ -2240,7 +2240,7 @@ QStyleOptionSpinBox::QStyleOptionSpinBox(int version)
\inmodule QtWidgets
This class is used for drawing the compatibility Q3ListView's
- items. \bold {It is not recommended for new classes}.
+ items. \b {It is not recommended for new classes}.
QStyleOptionQ3ListViewItem contains all the information that
QStyle functions need to draw the Q3ListView items.
@@ -2376,7 +2376,7 @@ QStyleOptionQ3ListViewItem::QStyleOptionQ3ListViewItem(int version)
\inmodule QtWidgets
- This class is used for drawing the compatibility Q3ListView. \bold
+ This class is used for drawing the compatibility Q3ListView. \b
{It is not recommended for new classes}.
QStyleOptionQ3ListView contains all the information that QStyle
@@ -2523,7 +2523,7 @@ QStyleOptionQ3ListView::QStyleOptionQ3ListView(int version)
\inmodule QtWidgets
This class is used for drawing the old Q3DockWindow and its
- parts. \bold {It is not recommended for new classes}.
+ parts. \b {It is not recommended for new classes}.
QStyleOptionQ3DockWindow contains all the information that QStyle
functions need to draw Q3DockWindow and its parts.
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index a24f42c5f1..5aab69983c 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -339,7 +339,7 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
// Find top level with native window (there might be dialogs that do not have one).
foreach (const QWidget *toplevel, QApplication::topLevelWidgets())
- if (toplevel->windowHandle())
+ if (toplevel->windowHandle() && toplevel->windowHandle()->handle())
if (const HWND topLevelHwnd = QApplicationPrivate::getHWNDForWidget(toplevel))
return topLevelHwnd;
@@ -698,7 +698,10 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
}
// Draw on backing store DC only for real widgets.
- const bool useFallback = !themeData.widget || painter->device()->devType() != QInternal::Widget
+ // Access paintDevice via engine since the painter may
+ // return the clip device which can still be a widget device in case of grabWidget().
+ const bool useFallback = !themeData.widget
+ || painter->paintEngine()->paintDevice()->devType() != QInternal::Widget
|| painter->opacity() != 1.0 || themeData.rotate
|| complexXForm || themeData.mirrorVertically
|| (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index d416f26f51..91e4a9c3c1 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -1475,7 +1475,7 @@ int QCompleter::completionCount() const
The sort order (i.e ascending or descending order) of the model is determined
dynamically by inspecting the contents of the model.
- \bold{Note:} The performance improvements described above cannot take place
+ \b{Note:} The performance improvements described above cannot take place
when the completer's \l caseSensitivity is different to the case sensitivity
used by the model's when sorting.
diff --git a/src/widgets/util/qscrollerproperties.cpp b/src/widgets/util/qscrollerproperties.cpp
index 8d6ad36014..b698252b07 100644
--- a/src/widgets/util/qscrollerproperties.cpp
+++ b/src/widgets/util/qscrollerproperties.cpp
@@ -329,7 +329,7 @@ void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &v
around the axis. The threshold must be in the range \c 0 to \c 1.
\value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an
- user initiated flick. Please note that this is the easing curve for the positions, \bold{not}
+ user initiated flick. Please note that this is the easing curve for the positions, \b{not}
the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in
velocity (1st derivative) and a constant deceleration (2nd derivative).
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index bed8dc2eae..fc2d046114 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -77,10 +77,10 @@ QT_BEGIN_NAMESPACE
The QSystemTrayIcon class can be used on the following platforms:
\list
- \o All supported versions of Windows.
- \o All window managers for X11 that implement the \l{freedesktop.org} system
+ \li All supported versions of Windows.
+ \li All window managers for X11 that implement the \l{freedesktop.org} system
tray specification, including recent versions of KDE and GNOME.
- \o All supported versions of Mac OS X. Note that the Growl
+ \li All supported versions of Mac OS X. Note that the Growl
notification system must be installed for
QSystemTrayIcon::showMessage() to display messages.
\endlist
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index 7cd77678e6..5392dd2f8e 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -934,10 +934,10 @@ QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) co
While a macro is composed, the stack is disabled. This means that:
\list
- \i indexChanged() and cleanChanged() are not emitted,
- \i canUndo() and canRedo() return false,
- \i calling undo() or redo() has no effect,
- \i the undo/redo actions are disabled.
+ \li indexChanged() and cleanChanged() are not emitted,
+ \li canUndo() and canRedo() return false,
+ \li calling undo() or redo() has no effect,
+ \li the undo/redo actions are disabled.
\endlist
The stack becomes enabled and appropriate signals are emitted when endMacro()
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index be250c54e1..80e125947e 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -109,21 +109,21 @@ Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets;
\list
- \o isDown() indicates whether the button is \e pressed down.
+ \li isDown() indicates whether the button is \e pressed down.
- \o isChecked() indicates whether the button is \e checked. Only
+ \li isChecked() indicates whether the button is \e checked. Only
checkable buttons can be checked and unchecked (see below).
- \o isEnabled() indicates whether the button can be pressed by the
+ \li isEnabled() indicates whether the button can be pressed by the
user. \note As opposed to other widgets, buttons derived from
QAbstractButton accepts mouse and context menu events
when disabled.
- \o setAutoRepeat() sets whether the button will auto-repeat if the
+ \li setAutoRepeat() sets whether the button will auto-repeat if the
user holds it down. \l autoRepeatDelay and \l autoRepeatInterval
define how auto-repetition is done.
- \o setCheckable() sets whether the button is a toggle button or not.
+ \li setCheckable() sets whether the button is a toggle button or not.
\endlist
@@ -138,16 +138,16 @@ Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets;
\list 1
- \o pressed() is emitted when the left mouse button is pressed while
+ \li pressed() is emitted when the left mouse button is pressed while
the mouse cursor is inside the button.
- \o released() is emitted when the left mouse button is released.
+ \li released() is emitted when the left mouse button is released.
- \o clicked() is emitted when the button is first pressed and then
+ \li clicked() is emitted when the button is first pressed and then
released, when the shortcut key is typed, or when click() or
animateClick() is called.
- \o toggled() is emitted when the state of a toggle button changes.
+ \li toggled() is emitted when the state of a toggle button changes.
\endlist
@@ -190,7 +190,7 @@ public:
void detectCheckedButton();
void notifyChecked(QAbstractButton *button);
bool exclusive;
- QMap<QAbstractButton*, int> mapping;
+ QHash<QAbstractButton*, int> mapping;
};
QButtonGroup::QButtonGroup(QObject *parent)
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 03ec21680d..a960ce8d9c 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -101,14 +101,14 @@ QT_BEGIN_NAMESPACE
following:
\list
- \o Control the scroll bars by setting their
+ \li Control the scroll bars by setting their
range, value, page step, and tracking their
movements.
- \o Draw the contents of the area in the viewport according
+ \li Draw the contents of the area in the viewport according
to the values of the scroll bars.
- \o Handle events received by the viewport in
+ \li Handle events received by the viewport in
viewportEvent() - notably resize events.
- \o Use \c{viewport->update()} to update the contents of the
+ \li Use \c{viewport->update()} to update the contents of the
viewport instead of \l{QWidget::update()}{update()}
as all painting operations take place on the viewport.
\endlist
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index be193f64f0..6aff2e9077 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -65,23 +65,23 @@ QT_BEGIN_NAMESPACE
\list 1
- \i \l value: The bounded integer that QAbstractSlider maintains.
+ \li \l value: The bounded integer that QAbstractSlider maintains.
- \i \l minimum: The lowest possible value.
+ \li \l minimum: The lowest possible value.
- \i \l maximum: The highest possible value.
+ \li \l maximum: The highest possible value.
- \i \l singleStep: The smaller of two natural steps that an
+ \li \l singleStep: The smaller of two natural steps that an
abstract sliders provides and typically corresponds to the user
pressing an arrow key.
- \i \l pageStep: The larger of two natural steps that an abstract
+ \li \l pageStep: The larger of two natural steps that an abstract
slider provides and typically corresponds to the user pressing
PageUp or PageDown.
- \i \l tracking: Whether slider tracking is enabled.
+ \li \l tracking: Whether slider tracking is enabled.
- \i \l sliderPosition: The current position of the slider. If \l
+ \li \l sliderPosition: The current position of the slider. If \l
tracking is enabled (the default), this is identical to \l value.
\endlist
@@ -95,21 +95,21 @@ QT_BEGIN_NAMESPACE
QAbstractSlider emits a comprehensive set of signals:
\table
- \header \i Signal \i Emitted when
- \row \i \l valueChanged()
- \i the value has changed. The \l tracking
+ \header \li Signal \li Emitted when
+ \row \li \l valueChanged()
+ \li the value has changed. The \l tracking
determines whether this signal is emitted during user
interaction.
- \row \i \l sliderPressed()
- \i the user starts to drag the slider.
- \row \i \l sliderMoved()
- \i the user drags the slider.
- \row \i \l sliderReleased()
- \i the user releases the slider.
- \row \i \l actionTriggered()
- \i a slider action was triggerd.
- \row \i \l rangeChanged()
- \i a the range has changed.
+ \row \li \l sliderPressed()
+ \li the user starts to drag the slider.
+ \row \li \l sliderMoved()
+ \li the user drags the slider.
+ \row \li \l sliderReleased()
+ \li the user releases the slider.
+ \row \li \l actionTriggered()
+ \li a slider action was triggerd.
+ \row \li \l rangeChanged()
+ \li a the range has changed.
\endtable
QAbstractSlider provides a virtual sliderChange() function that is
diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h
index dbcd14cb67..d03a1a3918 100644
--- a/src/widgets/widgets/qabstractslider.h
+++ b/src/widgets/widgets/qabstractslider.h
@@ -79,8 +79,6 @@ public:
void setMaximum(int);
int maximum() const;
- void setRange(int min, int max);
-
void setSingleStep(int);
int singleStep() const;
@@ -120,6 +118,7 @@ public:
public Q_SLOTS:
void setValue(int);
void setOrientation(Qt::Orientation);
+ void setRange(int min, int max);
Q_SIGNALS:
void valueChanged(int value);
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 331b4918bd..e9652a9869 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -90,11 +90,11 @@ QT_BEGIN_NAMESPACE
\list 1
- \i \l text: The text that is displayed in the QAbstractSpinBox.
+ \li \l text: The text that is displayed in the QAbstractSpinBox.
- \i \l alignment: The alignment of the text in the QAbstractSpinBox.
+ \li \l alignment: The alignment of the text in the QAbstractSpinBox.
- \i \l wrapping: Whether the QAbstractSpinBox wraps from the
+ \li \l wrapping: Whether the QAbstractSpinBox wraps from the
minimum value to the maximum value and vica versa.
\endlist
@@ -167,7 +167,7 @@ QAbstractSpinBox::~QAbstractSpinBox()
\inlineimage qspinbox-plusminus.png
\value UpDownArrows Little arrows in the classic style.
- \value PlusMinus \bold{+} and \bold{-} symbols.
+ \value PlusMinus \b{+} and \b{-} symbols.
\value NoButtons Don't display buttons.
\sa QAbstractSpinBox::buttonSymbols
@@ -918,17 +918,17 @@ void QAbstractSpinBox::paintEvent(QPaintEvent *)
The following keys are handled specifically:
\table
- \row \i Enter/Return
- \i This will reinterpret the text and emit a signal even if the value has not changed
+ \row \li Enter/Return
+ \li This will reinterpret the text and emit a signal even if the value has not changed
since last time a signal was emitted.
- \row \i Up
- \i This will invoke stepBy(1)
- \row \i Down
- \i This will invoke stepBy(-1)
- \row \i Page up
- \i This will invoke stepBy(10)
- \row \i Page down
- \i This will invoke stepBy(-10)
+ \row \li Up
+ \li This will invoke stepBy(1)
+ \row \li Down
+ \li This will invoke stepBy(-1)
+ \row \li Page up
+ \li This will invoke stepBy(10)
+ \row \li Page down
+ \li This will invoke stepBy(-10)
\endtable
*/
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 1541010646..129da9d94d 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -2001,9 +2001,9 @@ void QCalendarWidgetPrivate::_q_editingFinished()
setGridVisible() function:
\table
- \row \o
+ \row \li
\image qcalendarwidget-grid.png
- \row \o
+ \row \li
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 0
\endtable
@@ -2418,9 +2418,9 @@ void QCalendarWidget::showToday()
\table
\row
- \o \image qcalendarwidget-minimum.png
+ \li \image qcalendarwidget-minimum.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 1
\endtable
@@ -2469,9 +2469,9 @@ void QCalendarWidget::setMinimumDate(const QDate &date)
\table
\row
- \o \image qcalendarwidget-maximum.png
+ \li \image qcalendarwidget-maximum.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 2
\endtable
@@ -2638,9 +2638,9 @@ void QCalendarWidget::setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFor
\table
\row
- \o \inlineimage qcalendarwidget-grid.png
+ \li \inlineimage qcalendarwidget-grid.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 5
\endtable
diff --git a/src/widgets/widgets/qcheckbox.cpp b/src/widgets/widgets/qcheckbox.cpp
index 3bf2e39ef1..13440ac104 100644
--- a/src/widgets/widgets/qcheckbox.cpp
+++ b/src/widgets/widgets/qcheckbox.cpp
@@ -87,8 +87,8 @@ public:
non-exclusive checkboxes.
\table
- \row \o \inlineimage checkboxes-exclusive.png
- \o \inlineimage checkboxes-non-exclusive.png
+ \row \li \inlineimage checkboxes-exclusive.png
+ \li \inlineimage checkboxes-non-exclusive.png
\endtable
Whenever a checkbox is checked or cleared it emits the signal
@@ -121,14 +121,14 @@ public:
\table 100%
\row
- \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox
- \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \li \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox
+ \li A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
\row
- \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox
- \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \li \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox
+ \li A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
\row
- \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox
- \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \li \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox
+ \li A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QAbstractButton, QRadioButton, {fowler}{GUI Design Handbook: Check Box}
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index 5761c1299c..3d0996a9f5 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -103,12 +103,12 @@ QT_BEGIN_NAMESPACE
calendar widget can be retrieved with calendarWidget().
\table 100%
- \row \o \inlineimage windowsxp-datetimeedit.png Screenshot of a Windows XP style date time editing widget
- \o A date time editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage macintosh-datetimeedit.png Screenshot of a Macintosh style date time editing widget
- \o A date time editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage plastique-datetimeedit.png Screenshot of a Plastique style date time editing widget
- \o A date time editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage windowsxp-datetimeedit.png Screenshot of a Windows XP style date time editing widget
+ \li A date time editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage macintosh-datetimeedit.png Screenshot of a Macintosh style date time editing widget
+ \li A date time editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage plastique-datetimeedit.png Screenshot of a Plastique style date time editing widget
+ \li A date time editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QDateEdit, QTimeEdit, QDate, QTime
@@ -835,10 +835,10 @@ QString QDateTimeEdit::sectionText(Section section) const
Example format strings (assuming that the date is 2nd of July 1969):
\table
- \header \i Format \i Result
- \row \i dd.MM.yyyy \i 02.07.1969
- \row \i MMM d yy \i Jul 2 69
- \row \i MMMM d yy \i July 2 69
+ \header \li Format \li Result
+ \row \li dd.MM.yyyy \li 02.07.1969
+ \row \li MMM d yy \li Jul 2 69
+ \row \li MMMM d yy \li July 2 69
\endtable
Note that if you specify a two digit year, it will be interpreted
@@ -1520,22 +1520,22 @@ void QDateTimeEdit::mousePressEvent(QMouseEvent *event)
class:
\list
- \o \l{QDateTimeEdit::time}{time} holds the date displayed by the widget.
- \o \l{QDateTimeEdit::minimumTime}{minimumTime} defines the minimum (earliest) time
+ \li \l{QDateTimeEdit::time}{time} holds the date displayed by the widget.
+ \li \l{QDateTimeEdit::minimumTime}{minimumTime} defines the minimum (earliest) time
that can be set by the user.
- \o \l{QDateTimeEdit::maximumTime}{maximumTime} defines the maximum (latest) time
+ \li \l{QDateTimeEdit::maximumTime}{maximumTime} defines the maximum (latest) time
that can be set by the user.
- \o \l{QDateTimeEdit::displayFormat}{displayFormat} contains a string that is used
+ \li \l{QDateTimeEdit::displayFormat}{displayFormat} contains a string that is used
to format the time displayed in the widget.
\endlist
\table 100%
- \row \o \inlineimage windowsxp-timeedit.png Screenshot of a Windows XP style time editing widget
- \o A time editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage macintosh-timeedit.png Screenshot of a Macintosh style time editing widget
- \o A time editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage plastique-timeedit.png Screenshot of a Plastique style time editing widget
- \o A time editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage windowsxp-timeedit.png Screenshot of a Windows XP style time editing widget
+ \li A time editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage macintosh-timeedit.png Screenshot of a Macintosh style time editing widget
+ \li A time editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage plastique-timeedit.png Screenshot of a Plastique style time editing widget
+ \li A time editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QDateEdit, QDateTimeEdit
@@ -1575,22 +1575,22 @@ QTimeEdit::QTimeEdit(const QTime &time, QWidget *parent)
class:
\list
- \o \l{QDateTimeEdit::date}{date} holds the date displayed by the widget.
- \o \l{QDateTimeEdit::minimumDate}{minimumDate} defines the minimum (earliest)
+ \li \l{QDateTimeEdit::date}{date} holds the date displayed by the widget.
+ \li \l{QDateTimeEdit::minimumDate}{minimumDate} defines the minimum (earliest)
date that can be set by the user.
- \o \l{QDateTimeEdit::maximumDate}{maximumDate} defines the maximum (latest) date
+ \li \l{QDateTimeEdit::maximumDate}{maximumDate} defines the maximum (latest) date
that can be set by the user.
- \o \l{QDateTimeEdit::displayFormat}{displayFormat} contains a string that is used
+ \li \l{QDateTimeEdit::displayFormat}{displayFormat} contains a string that is used
to format the date displayed in the widget.
\endlist
\table 100%
- \row \o \inlineimage windowsxp-dateedit.png Screenshot of a Windows XP style date editing widget
- \o A date editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage macintosh-dateedit.png Screenshot of a Macintosh style date editing widget
- \o A date editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage plastique-dateedit.png Screenshot of a Plastique style date editing widget
- \o A date editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage windowsxp-dateedit.png Screenshot of a Windows XP style date editing widget
+ \li A date editing widget shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage macintosh-dateedit.png Screenshot of a Macintosh style date editing widget
+ \li A date editing widget shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage plastique-dateedit.png Screenshot of a Plastique style date editing widget
+ \li A date editing widget shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QTimeEdit, QDateTimeEdit
diff --git a/src/widgets/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp
index 566652b8f5..e3fe390f2a 100644
--- a/src/widgets/widgets/qdial.cpp
+++ b/src/widgets/widgets/qdial.cpp
@@ -230,10 +230,10 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const
\l {QAbstractSlider::pageStep} {pageStep}.
\table
- \row \o \inlineimage plastique-dial.png Screenshot of a dial in the Plastique widget style
- \o \inlineimage windowsxp-dial.png Screenshot of a dial in the Windows XP widget style
- \o \inlineimage macintosh-dial.png Screenshot of a dial in the Macintosh widget style
- \row \o {3,1} Dials shown in various widget styles (from left to right):
+ \row \li \inlineimage plastique-dial.png Screenshot of a dial in the Plastique widget style
+ \li \inlineimage windowsxp-dial.png Screenshot of a dial in the Windows XP widget style
+ \li \inlineimage macintosh-dial.png Screenshot of a dial in the Macintosh widget style
+ \row \li {3,1} Dials shown in various widget styles (from left to right):
\l{Plastique Style Widget Gallery}{Plastique},
\l{Windows XP Style Widget Gallery}{Windows XP},
\l{Macintosh Style Widget Gallery}{Macintosh}.
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index d1084168a9..14643e77f6 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -76,9 +76,9 @@ QT_BEGIN_NAMESPACE
Most buttons for a dialog follow certain roles. Such roles include:
\list
- \o Accepting or rejecting the dialog.
- \o Asking for help.
- \o Performing actions on the dialog itself (such as resetting fields or
+ \li Accepting or rejecting the dialog.
+ \li Asking for help.
+ \li Performing actions on the dialog itself (such as resetting fields or
applying changes).
\endlist
@@ -104,35 +104,35 @@ QT_BEGIN_NAMESPACE
Currently the buttons are laid out in the following way if the button box is horizontal:
\table
- \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal
- \o Button box laid out in horizontal GnomeLayout
- \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal
- \o Button box laid out in horizontal KdeLayout
- \row \o \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal
- \o Button box laid out in horizontal MacLayout
- \row \o \inlineimage buttonbox-winlayout-horizontal.png WinLayout Horizontal
- \o Button box laid out in horizontal WinLayout
+ \row \li \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal
+ \li Button box laid out in horizontal GnomeLayout
+ \row \li \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal
+ \li Button box laid out in horizontal KdeLayout
+ \row \li \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal
+ \li Button box laid out in horizontal MacLayout
+ \row \li \inlineimage buttonbox-winlayout-horizontal.png WinLayout Horizontal
+ \li Button box laid out in horizontal WinLayout
\endtable
The buttons are laid out the following way if the button box is vertical:
\table
- \row \o GnomeLayout
- \o KdeLayout
- \o MacLayout
- \o WinLayout
- \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical
- \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical
- \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical
- \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical
+ \row \li GnomeLayout
+ \li KdeLayout
+ \li MacLayout
+ \li WinLayout
+ \row \li \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical
+ \li \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical
+ \li \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical
+ \li \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical
\endtable
Additionally, button boxes that contain only buttons with ActionRole or
HelpRole can be considered modeless and have an alternate look on Mac OS X:
\table
- \row \o modeless horizontal MacLayout
- \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout
+ \row \li modeless horizontal MacLayout
+ \li \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout
\endtable
When a button is clicked in the button box, the clicked() signal is emitted
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index a90c754cee..e40b109455 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -1538,22 +1538,22 @@ QAction * QDockWidget::toggleViewAction() const
Here are some tips for implementing custom title bars:
\list
- \o Mouse events that are not explicitly handled by the title bar widget
+ \li Mouse events that are not explicitly handled by the title bar widget
must be ignored by calling QMouseEvent::ignore(). These events then
propagate to the QDockWidget parent, which handles them in the usual
manner, moving when the title bar is dragged, docking and undocking
when it is double-clicked, etc.
- \o When DockWidgetVerticalTitleBar is set on QDockWidget, the title
+ \li When DockWidgetVerticalTitleBar is set on QDockWidget, the title
bar widget is repositioned accordingly. In resizeEvent(), the title
bar should check what orientation it should assume:
\snippet doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp 0
- \o The title bar widget must have a valid QWidget::sizeHint() and
+ \li The title bar widget must have a valid QWidget::sizeHint() and
QWidget::minimumSizeHint(). These functions should take into account
the current orientation of the title bar.
- \o It is not possible to remove a title bar from a dock widget. However,
+ \li It is not possible to remove a title bar from a dock widget. However,
a similar effect can be achieved by setting a default constructed
QWidget as the title bar widget.
\endlist
diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp
index cae4137803..29c213f7af 100644
--- a/src/widgets/widgets/qframe.cpp
+++ b/src/widgets/widgets/qframe.cpp
@@ -97,15 +97,15 @@ inline void QFramePrivate::init()
border: \l lineWidth, \l midLineWidth, and \l frameWidth.
\list
- \o The line width is the width of the frame border. It can be modified
+ \li The line width is the width of the frame border. It can be modified
to customize the frame's appearance.
- \o The mid-line width specifies the width of an extra line in the
+ \li The mid-line width specifies the width of an extra line in the
middle of the frame, which uses a third color to obtain a special
3D effect. Notice that a mid-line is only drawn for \l Box, \l
HLine and \l VLine frames that are raised or sunken.
- \o The frame width is determined by the frame style, and the frameWidth()
+ \li The frame width is determined by the frame style, and the frameWidth()
function is used to obtain the value defined for the style used.
\endlist
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 17f3a9323a..cf3e14871f 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -172,12 +172,12 @@ void QGroupBoxPrivate::click()
\snippet examples/widgets/groupbox/window.cpp 2
\table 100%
- \row \o \inlineimage windowsxp-groupbox.png Screenshot of a Windows XP style group box
- \o \inlineimage macintosh-groupbox.png Screenshot of a Macintosh style group box
- \o \inlineimage plastique-groupbox.png Screenshot of a Plastique style group box
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} group box.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} group box.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} group box.
+ \row \li \inlineimage windowsxp-groupbox.png Screenshot of a Windows XP style group box
+ \li \inlineimage macintosh-groupbox.png Screenshot of a Macintosh style group box
+ \li \inlineimage plastique-groupbox.png Screenshot of a Plastique style group box
+ \row \li A \l{Windows XP Style Widget Gallery}{Windows XP style} group box.
+ \li A \l{Macintosh Style Widget Gallery}{Macintosh style} group box.
+ \li A \l{Plastique Style Widget Gallery}{Plastique style} group box.
\endtable
\sa QButtonGroup, {Group Box Example}
@@ -287,9 +287,9 @@ QString QGroupBox::title() const
the following list:
\list
- \i Qt::AlignLeft aligns the title text with the left-hand side of the group box.
- \i Qt::AlignRight aligns the title text with the right-hand side of the group box.
- \i Qt::AlignHCenter aligns the title text with the horizontal center of the group box.
+ \li Qt::AlignLeft aligns the title text with the left-hand side of the group box.
+ \li Qt::AlignRight aligns the title text with the right-hand side of the group box.
+ \li Qt::AlignHCenter aligns the title text with the horizontal center of the group box.
\endlist
The default alignment is Qt::AlignLeft.
@@ -516,7 +516,7 @@ QSize QGroupBox::minimumSizeHint() const
By default, this property is disabled; i.e. group boxes are not flat unless
explicitly specified.
- \bold{Note:} In some styles, flat and non-flat group boxes have similar
+ \b{Note:} In some styles, flat and non-flat group boxes have similar
representations and may not be as distinguishable as they are in other
styles.
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index d23fab4083..82e56f3354 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -76,20 +76,20 @@ QT_BEGIN_NAMESPACE
A QLabel can contain any of the following content types:
\table
- \header \o Content \o Setting
- \row \o Plain text
- \o Pass a QString to setText().
- \row \o Rich text
- \o Pass a QString that contains rich text to setText().
- \row \o A pixmap
- \o Pass a QPixmap to setPixmap().
- \row \o A movie
- \o Pass a QMovie to setMovie().
- \row \o A number
- \o Pass an \e int or a \e double to setNum(), which converts
+ \header \li Content \li Setting
+ \row \li Plain text
+ \li Pass a QString to setText().
+ \row \li Rich text
+ \li Pass a QString that contains rich text to setText().
+ \row \li A pixmap
+ \li Pass a QPixmap to setPixmap().
+ \row \li A movie
+ \li Pass a QMovie to setMovie().
+ \row \li A number
+ \li Pass an \e int or a \e double to setNum(), which converts
the number to plain text.
- \row \o Nothing
- \o The same as an empty plain text. This is the default. Set
+ \row \li Nothing
+ \li The same as an empty plain text. This is the default. Set
by clear().
\endtable
@@ -134,14 +134,14 @@ QT_BEGIN_NAMESPACE
\table 100%
\row
- \o \inlineimage macintosh-label.png Screenshot of a Macintosh style label
- \o A label shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \li \inlineimage macintosh-label.png Screenshot of a Macintosh style label
+ \li A label shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
\row
- \o \inlineimage plastique-label.png Screenshot of a Plastique style label
- \o A label shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \li \inlineimage plastique-label.png Screenshot of a Plastique style label
+ \li A label shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\row
- \o \inlineimage windowsxp-label.png Screenshot of a Windows XP style label
- \o A label shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \li \inlineimage windowsxp-label.png Screenshot of a Windows XP style label
+ \li A label shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
\endtable
\sa QLineEdit, QTextEdit, QPixmap, QMovie,
@@ -655,7 +655,7 @@ int QLabel::heightForWidth(int w) const
QDesktopServices::openUrl() instead of emitting the
linkActivated() signal.
- \bold{Note:} The textInteractionFlags set on the label need to include
+ \b{Note:} The textInteractionFlags set on the label need to include
either LinksAccessibleByMouse or LinksAccessibleByKeyboard.
The default value is false.
@@ -723,7 +723,7 @@ Qt::TextInteractionFlags QLabel::textInteractionFlags() const
\sa selectedText()
- \bold{Note:} The textInteractionFlags set on the label need to include
+ \b{Note:} The textInteractionFlags set on the label need to include
either TextSelectableByMouse or TextSelectableByKeyboard.
\since 4.7
@@ -751,7 +751,7 @@ void QLabel::setSelection(int start, int length)
\sa selectedText()
- \bold{Note:} The textInteractionFlags set on the label need to include
+ \b{Note:} The textInteractionFlags set on the label need to include
either TextSelectableByMouse or TextSelectableByKeyboard.
\since 4.7
@@ -775,7 +775,7 @@ bool QLabel::hasSelectedText() const
\sa hasSelectedText()
- \bold{Note:} The textInteractionFlags set on the label need to include
+ \b{Note:} The textInteractionFlags set on the label need to include
either TextSelectableByMouse or TextSelectableByKeyboard.
\since 4.7
@@ -794,7 +794,7 @@ QString QLabel::selectedText() const
\sa selectedText()
- \bold{Note:} The textInteractionFlags set on the label need to include
+ \b{Note:} The textInteractionFlags set on the label need to include
either TextSelectableByMouse or TextSelectableByKeyboard.
\since 4.7
diff --git a/src/widgets/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp
index 71e08fdaeb..4639b15834 100644
--- a/src/widgets/widgets/qlcdnumber.cpp
+++ b/src/widgets/widgets/qlcdnumber.cpp
@@ -108,13 +108,13 @@ public:
Sinclair Spectrum\endlink.
\table
- \row \o \inlineimage motif-lcdnumber.png Screenshot of a Motif style LCD number widget
+ \row \li \inlineimage motif-lcdnumber.png Screenshot of a Motif style LCD number widget
\inlineimage cde-lcdnumber.png Screenshot of a CDE style LCD number widget
\inlineimage windows-lcdnumber.png Screenshot of a Windows style LCD number widget
\inlineimage windowsxp-lcdnumber.png Screenshot of a Windows XP style LCD number widget
\inlineimage macintosh-lcdnumber.png Screenshot of a Macintosh style LCD number widget
\inlineimage plastique-lcdnumber.png Screenshot of a Plastique style LCD number widget
- \row \o LCD number widgets shown in various widget styles (from left to right):
+ \row \li LCD number widgets shown in various widget styles (from left to right):
\l{Motif Style Widget Gallery}{Motif}, \l{CDE Style Widget Gallery}{CDE},
\l{Windows Style Widget Gallery}{Windows}, \l{Windows XP Style Widget Gallery}{Windows XP},
\l{Macintosh Style Widget Gallery}{Macintosh}, \l{Plastique Style Widget Gallery}{Plastique}.
@@ -1184,14 +1184,14 @@ void QLCDNumberPrivate::drawSegment(const QPoint &pos, char segmentNo, QPainter
\brief the style of the LCDNumber
\table
- \header \i Style \i Result
- \row \i \c Outline
- \i Produces raised segments filled with the background color
- \row \i \c Filled
+ \header \li Style \li Result
+ \row \li \c Outline
+ \li Produces raised segments filled with the background color
+ \row \li \c Filled
(this is the default).
- \i Produces raised segments filled with the foreground color.
- \row \i \c Flat
- \i Produces flat segments filled with the foreground color.
+ \li Produces raised segments filled with the foreground color.
+ \row \li \c Flat
+ \li Produces flat segments filled with the foreground color.
\endtable
\c Outline and \c Filled will additionally use
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 7118881ef2..07843136ff 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -177,39 +177,39 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
that presents some of these editing options.
\target desc
\table
- \header \i Keypress \i Action
- \row \i Left Arrow \i Moves the cursor one character to the left.
- \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
- \row \i Right Arrow \i Moves the cursor one character to the right.
- \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
- \row \i Ctrl+A \i Select all.
- \row \i Ctrl+C \i Copies the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copies the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into line edit.
- \row \i Shift+Insert \i Pastes the clipboard text into line edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last undone operation.
+ \header \li Keypress \li Action
+ \row \li Left Arrow \li Moves the cursor one character to the left.
+ \row \li Shift+Left Arrow \li Moves and selects text one character to the left.
+ \row \li Right Arrow \li Moves the cursor one character to the right.
+ \row \li Shift+Right Arrow \li Moves and selects text one character to the right.
+ \row \li Home \li Moves the cursor to the beginning of the line.
+ \row \li End \li Moves the cursor to the end of the line.
+ \row \li Backspace \li Deletes the character to the left of the cursor.
+ \row \li Ctrl+Backspace \li Deletes the word to the left of the cursor.
+ \row \li Delete \li Deletes the character to the right of the cursor.
+ \row \li Ctrl+Delete \li Deletes the word to the right of the cursor.
+ \row \li Ctrl+A \li Select all.
+ \row \li Ctrl+C \li Copies the selected text to the clipboard.
+ \row \li Ctrl+Insert \li Copies the selected text to the clipboard.
+ \row \li Ctrl+K \li Deletes to the end of the line.
+ \row \li Ctrl+V \li Pastes the clipboard text into line edit.
+ \row \li Shift+Insert \li Pastes the clipboard text into line edit.
+ \row \li Ctrl+X \li Deletes the selected text and copies it to the clipboard.
+ \row \li Shift+Delete \li Deletes the selected text and copies it to the clipboard.
+ \row \li Ctrl+Z \li Undoes the last operation.
+ \row \li Ctrl+Y \li Redoes the last undone operation.
\endtable
Any other key sequence that represents a valid character, will
cause the character to be inserted into the line edit.
\table 100%
- \row \o \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit
- \o A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit
- \o A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit
- \o A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit
+ \li A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit
+ \li A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit
+ \li A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
@@ -1096,26 +1096,26 @@ QMargins QLineEdit::textMargins() const
where a character is \e{permitted but not required}.
\table
- \header \i Character \i Meaning
- \row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
- \row \i \c a \i ASCII alphabetic character permitted but not required.
- \row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
- \row \i \c n \i ASCII alphanumeric character permitted but not required.
- \row \i \c X \i Any character required.
- \row \i \c x \i Any character permitted but not required.
- \row \i \c 9 \i ASCII digit required. 0-9.
- \row \i \c 0 \i ASCII digit permitted but not required.
- \row \i \c D \i ASCII digit required. 1-9.
- \row \i \c d \i ASCII digit permitted but not required (1-9).
- \row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
- \row \i \c H \i Hexadecimal character required. A-F, a-f, 0-9.
- \row \i \c h \i Hexadecimal character permitted but not required.
- \row \i \c B \i Binary character required. 0-1.
- \row \i \c b \i Binary character permitted but not required.
- \row \i \c > \i All following alphabetic characters are uppercased.
- \row \i \c < \i All following alphabetic characters are lowercased.
- \row \i \c ! \i Switch off case conversion.
- \row \i \tt{\\} \i Use \tt{\\} to escape the special
+ \header \li Character \li Meaning
+ \row \li \c A \li ASCII alphabetic character required. A-Z, a-z.
+ \row \li \c a \li ASCII alphabetic character permitted but not required.
+ \row \li \c N \li ASCII alphanumeric character required. A-Z, a-z, 0-9.
+ \row \li \c n \li ASCII alphanumeric character permitted but not required.
+ \row \li \c X \li Any character required.
+ \row \li \c x \li Any character permitted but not required.
+ \row \li \c 9 \li ASCII digit required. 0-9.
+ \row \li \c 0 \li ASCII digit permitted but not required.
+ \row \li \c D \li ASCII digit required. 1-9.
+ \row \li \c d \li ASCII digit permitted but not required (1-9).
+ \row \li \c # \li ASCII digit or plus/minus sign permitted but not required.
+ \row \li \c H \li Hexadecimal character required. A-F, a-f, 0-9.
+ \row \li \c h \li Hexadecimal character permitted but not required.
+ \row \li \c B \li Binary character required. 0-1.
+ \row \li \c b \li Binary character permitted but not required.
+ \row \li \c > \li All following alphabetic characters are uppercased.
+ \row \li \c < \li All following alphabetic characters are lowercased.
+ \row \li \c ! \li Switch off case conversion.
+ \row \li \tt{\\} \li Use \tt{\\} to escape the special
characters listed above to use them as
separators.
\endtable
@@ -1127,11 +1127,11 @@ QMargins QLineEdit::textMargins() const
Examples:
\table
- \header \i Mask \i Notes
- \row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
- \row \i \c HH:HH:HH:HH:HH:HH;_ \i MAC address
- \row \i \c 0000-00-00 \i ISO Date; blanks are \c space
- \row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
+ \header \li Mask \li Notes
+ \row \li \c 000.000.000.000;_ \li IP address; blanks are \c{_}.
+ \row \li \c HH:HH:HH:HH:HH:HH;_ \li MAC address
+ \row \li \c 0000-00-00 \li ISO Date; blanks are \c space
+ \row \li \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \li License number;
blanks are \c - and all (alphabetic) characters are converted to
uppercase.
\endtable
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 73ba0cc15e..7607f2f238 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1480,12 +1480,12 @@ bool QMainWindow::event(QEvent *event)
moved to that. This means a couple of things.
\list
- \i QToolBars in this toolbar area are not movable and you cannot drag other
+ \li QToolBars in this toolbar area are not movable and you cannot drag other
toolbars to it
- \i Toolbar breaks are not respected or preserved
- \i Any custom widgets in the toolbar will not be shown if the toolbar
+ \li Toolbar breaks are not respected or preserved
+ \li Any custom widgets in the toolbar will not be shown if the toolbar
becomes too small (only actions will be shown)
- \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
+ \li Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
the toolbars out and back into the regular toolbar and vice versa when you swap out.
\endlist
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 7d73a66c5c..36fba72963 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -92,8 +92,8 @@
slots and are easily connected to menu entries.
\table
- \row \o \inlineimage mdi-cascade.png
- \o \inlineimage mdi-tile.png
+ \row \li \inlineimage mdi-cascade.png
+ \li \inlineimage mdi-tile.png
\endtable
\note The default scroll bar property for QMdiArea is Qt::ScrollBarAlwaysOff.
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 7ebfdbecae..3fb2a6122c 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -1218,9 +1218,9 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
\table 100%
\row
- \o \inlineimage plastique-menu.png
- \o \inlineimage windowsxp-menu.png
- \o \inlineimage macintosh-menu.png
+ \li \inlineimage plastique-menu.png
+ \li \inlineimage windowsxp-menu.png
+ \li \inlineimage macintosh-menu.png
\endtable
\caption Fig. A menu shown in \l{Plastique Style Widget Gallery}{Plastique widget style},
\l{Windows XP Style Widget Gallery}{Windows XP widget style},
@@ -1284,7 +1284,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
See the \l{mainwindows/menus}{Menus} example for an example of how
to use QMenuBar and QMenu in your application.
- \bold{Important inherited functions:} addAction(), removeAction(), clear(),
+ \b{Important inherited functions:} addAction(), removeAction(), clear(),
addSeparator(), and addMenu().
\sa QMenuBar, {fowler}{GUI Design Handbook: Menu, Drop-Down and Pop-Up},
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 16e486e77f..11f6592cc9 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -621,17 +621,17 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
\table
- \row \o \inlineimage plastique-menubar.png A menu bar shown in the
+ \row \li \inlineimage plastique-menubar.png A menu bar shown in the
Plastique widget style.
- \o The \l{QPlastiqueStyle}{Plastique widget style}, like most
+ \li The \l{QPlastiqueStyle}{Plastique widget style}, like most
other styles, handles the \gui{Help} menu in the same way as it
handles any other menu.
- \row \o \inlineimage motif-menubar.png A menu bar shown in the
+ \row \li \inlineimage motif-menubar.png A menu bar shown in the
Motif widget style.
- \o The \l{QMotifStyle}{Motif widget style} treats \gui{Help} menus
+ \li The \l{QMotifStyle}{Motif widget style} treats \gui{Help} menus
in a special way, placing them at right-hand end of the menu bar.
\endtable
@@ -652,18 +652,18 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
the strings looked for and where the entry is placed if matched:
\table
- \header \i String matches \i Placement \i Notes
- \row \i about.*
- \i Application Menu | About <application name>
- \i The application name is fetched from the \c {Info.plist} file
+ \header \li String matches \li Placement \li Notes
+ \row \li about.*
+ \li Application Menu | About <application name>
+ \li The application name is fetched from the \c {Info.plist} file
(see note below). If this entry is not found no About item
will appear in the Application Menu.
- \row \i config, options, setup, settings or preferences
- \i Application Menu | Preferences
- \i If this entry is not found the Settings item will be disabled
- \row \i quit or exit
- \i Application Menu | Quit <application name>
- \i If this entry is not found a default Quit item will be
+ \row \li config, options, setup, settings or preferences
+ \li Application Menu | Preferences
+ \li If this entry is not found the Settings item will be disabled
+ \row \li quit or exit
+ \li Application Menu | Quit <application name>
+ \li If this entry is not found a default Quit item will be
created to call QApplication::quit()
\endtable
@@ -676,12 +676,12 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
\snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
- \bold{Note:} Do \e{not} call QMainWindow::menuBar() to create the
+ \b{Note:} Do \e{not} call QMainWindow::menuBar() to create the
shared menu bar, because that menu bar will have the QMainWindow
as its parent. That menu bar would only be displayed for the
parent QMainWindow.
- \bold{Note:} The text used for the application name in the menu
+ \b{Note:} The text used for the application name in the menu
bar is obtained from the value set in the \c{Info.plist} file in
the application's bundle. See \l{Deploying an Application on
Mac OS X} for more information.
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index de6cb6a283..fad2d4e747 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1081,19 +1081,19 @@ void QPlainTextEditPrivate::ensureViewportLayouted()
When QPlainTextEdit is used read-only the key bindings are limited to
navigation, and text may only be selected with the mouse:
\table
- \header \i Keypresses \i Action
- \row \i Qt::UpArrow \i Moves one line up.
- \row \i Qt::DownArrow \i Moves one line down.
- \row \i Qt::LeftArrow \i Moves one character to the left.
- \row \i Qt::RightArrow \i Moves one character to the right.
- \row \i PageUp \i Moves one (viewport) page up.
- \row \i PageDown \i Moves one (viewport) page down.
- \row \i Home \i Moves to the beginning of the text.
- \row \i End \i Moves to the end of the text.
- \row \i Alt+Wheel
- \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
- \row \i Ctrl+A \i Selects all text.
+ \header \li Keypresses \li Action
+ \row \li Qt::UpArrow \li Moves one line up.
+ \row \li Qt::DownArrow \li Moves one line down.
+ \row \li Qt::LeftArrow \li Moves one character to the left.
+ \row \li Qt::RightArrow \li Moves one character to the right.
+ \row \li PageUp \li Moves one (viewport) page up.
+ \row \li PageDown \li Moves one (viewport) page down.
+ \row \li Home \li Moves to the beginning of the text.
+ \row \li End \li Moves to the end of the text.
+ \row \li Alt+Wheel
+ \li Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \li Ctrl+Wheel \li Zooms the text.
+ \row \li Ctrl+A \li Selects all text.
\endtable
@@ -1127,34 +1127,34 @@ void QPlainTextEditPrivate::ensureViewportLayouted()
The list of key bindings which are implemented for editing:
\table
- \header \i Keypresses \i Action
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+C \i Copy the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into text edit.
- \row \i Shift+Insert \i Pastes the clipboard text into text edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last operation.
- \row \i LeftArrow \i Moves the cursor one character to the left.
- \row \i Ctrl+LeftArrow \i Moves the cursor one word to the left.
- \row \i RightArrow \i Moves the cursor one character to the right.
- \row \i Ctrl+RightArrow \i Moves the cursor one word to the right.
- \row \i UpArrow \i Moves the cursor one line up.
- \row \i Ctrl+UpArrow \i Moves the cursor one word up.
- \row \i DownArrow \i Moves the cursor one line down.
- \row \i Ctrl+Down Arrow \i Moves the cursor one word down.
- \row \i PageUp \i Moves the cursor one page up.
- \row \i PageDown \i Moves the cursor one page down.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Ctrl+End \i Moves the cursor to the end of the text.
- \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
+ \header \li Keypresses \li Action
+ \row \li Backspace \li Deletes the character to the left of the cursor.
+ \row \li Delete \li Deletes the character to the right of the cursor.
+ \row \li Ctrl+C \li Copy the selected text to the clipboard.
+ \row \li Ctrl+Insert \li Copy the selected text to the clipboard.
+ \row \li Ctrl+K \li Deletes to the end of the line.
+ \row \li Ctrl+V \li Pastes the clipboard text into text edit.
+ \row \li Shift+Insert \li Pastes the clipboard text into text edit.
+ \row \li Ctrl+X \li Deletes the selected text and copies it to the clipboard.
+ \row \li Shift+Delete \li Deletes the selected text and copies it to the clipboard.
+ \row \li Ctrl+Z \li Undoes the last operation.
+ \row \li Ctrl+Y \li Redoes the last operation.
+ \row \li LeftArrow \li Moves the cursor one character to the left.
+ \row \li Ctrl+LeftArrow \li Moves the cursor one word to the left.
+ \row \li RightArrow \li Moves the cursor one character to the right.
+ \row \li Ctrl+RightArrow \li Moves the cursor one word to the right.
+ \row \li UpArrow \li Moves the cursor one line up.
+ \row \li Ctrl+UpArrow \li Moves the cursor one word up.
+ \row \li DownArrow \li Moves the cursor one line down.
+ \row \li Ctrl+Down Arrow \li Moves the cursor one word down.
+ \row \li PageUp \li Moves the cursor one page up.
+ \row \li PageDown \li Moves the cursor one page down.
+ \row \li Home \li Moves the cursor to the beginning of the line.
+ \row \li Ctrl+Home \li Moves the cursor to the beginning of the text.
+ \row \li End \li Moves the cursor to the end of the line.
+ \row \li Ctrl+End \li Moves the cursor to the end of the text.
+ \row \li Alt+Wheel \li Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \li Ctrl+Wheel \li Zooms the text.
\endtable
To select (mark) text hold down the Shift key whilst pressing one
diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp
index eabed2ee62..816b847cf5 100644
--- a/src/widgets/widgets/qprogressbar.cpp
+++ b/src/widgets/widgets/qprogressbar.cpp
@@ -196,12 +196,12 @@ bool QProgressBarPrivate::repaintRequired() const
they are unable to determine the size of the item being downloaded.
\table
- \row \o \inlineimage macintosh-progressbar.png Screenshot of a Macintosh style progress bar
- \o A progress bar shown in the Macintosh widget style.
- \row \o \inlineimage windowsxp-progressbar.png Screenshot of a Windows XP style progress bar
- \o A progress bar shown in the Windows XP widget style.
- \row \o \inlineimage plastique-progressbar.png Screenshot of a Plastique style progress bar
- \o A progress bar shown in the Plastique widget style.
+ \row \li \inlineimage macintosh-progressbar.png Screenshot of a Macintosh style progress bar
+ \li A progress bar shown in the Macintosh widget style.
+ \row \li \inlineimage windowsxp-progressbar.png Screenshot of a Windows XP style progress bar
+ \li A progress bar shown in the Windows XP widget style.
+ \row \li \inlineimage plastique-progressbar.png Screenshot of a Plastique style progress bar
+ \li A progress bar shown in the Plastique widget style.
\endtable
\sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index 99252c43dc..7ca5dcb486 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -126,13 +126,13 @@ QT_BEGIN_NAMESPACE
The most important modes or states are:
\list
- \i Available or not (grayed out, disabled).
- \i Standard push button, toggling push button or menu button.
- \i On or off (only for toggling push buttons).
- \i Default or normal. The default button in a dialog can generally
+ \li Available or not (grayed out, disabled).
+ \li Standard push button, toggling push button or menu button.
+ \li On or off (only for toggling push buttons).
+ \li Default or normal. The default button in a dialog can generally
be "clicked" using the Enter or Return key.
- \i Auto-repeat or not.
- \i Pressed down or not.
+ \li Auto-repeat or not.
+ \li Pressed down or not.
\endlist
As a general rule, use a push button when the application or
@@ -160,18 +160,18 @@ QT_BEGIN_NAMESPACE
check boxes (see QCheckBox).
\table 100%
- \row \o \inlineimage macintosh-pushbutton.png Screenshot of a Macintosh style push button
- \o A push button shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage macintosh-pushbutton.png Screenshot of a Macintosh style push button
+ \li A push button shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
Note that when a button's width becomes smaller than 50 or
its height becomes smaller than 30, the button's corners are
changed from round to square. Use the setMinimumSize()
function to prevent this behavior.
- \row \o \inlineimage windowsxp-pushbutton.png Screenshot of a Windows XP style push button
- \o A push button shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-pushbutton.png Screenshot of a Plastique style push button
- \o A push button shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage windowsxp-pushbutton.png Screenshot of a Windows XP style push button
+ \li A push button shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage plastique-pushbutton.png Screenshot of a Plastique style push button
+ \li A push button shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
In Qt, the QAbstractButton base class provides most of the modes
@@ -518,9 +518,9 @@ void QPushButton::focusOutEvent(QFocusEvent *e)
\table 100%
\row
- \o \inlineimage plastique-pushbutton-menu.png Screenshot of a Plastique style push button with popup menu.
- \o \inlineimage cleanlooks-pushbutton-menu.png Screenshot of a Cleanlooks style push button with popup menu.
- \o Push buttons with popup menus shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}
+ \li \inlineimage plastique-pushbutton-menu.png Screenshot of a Plastique style push button with popup menu.
+ \li \inlineimage cleanlooks-pushbutton-menu.png Screenshot of a Cleanlooks style push button with popup menu.
+ \li Push buttons with popup menus shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}
(left) and \l{Cleanlooks Style Widget Gallery}{Cleanlooks widget style} (right).
\endtable
diff --git a/src/widgets/widgets/qradiobutton.cpp b/src/widgets/widgets/qradiobutton.cpp
index 792550949b..11cd89bca2 100644
--- a/src/widgets/widgets/qradiobutton.cpp
+++ b/src/widgets/widgets/qradiobutton.cpp
@@ -116,12 +116,12 @@ void QRadioButtonPrivate::init()
toggle(), pressed(), released(), clicked(), and toggled().
\table 100%
- \row \o \inlineimage plastique-radiobutton.png Screenshot of a Plastique radio button
- \o A radio button shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \row \o \inlineimage windows-radiobutton.png Screenshot of a Windows XP radio button
- \o A radio button shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage macintosh-radiobutton.png Screenshot of a Macintosh radio button
- \o A radio button shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage plastique-radiobutton.png Screenshot of a Plastique radio button
+ \li A radio button shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage windows-radiobutton.png Screenshot of a Windows XP radio button
+ \li A radio button shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage macintosh-radiobutton.png Screenshot of a Macintosh radio button
+ \li A radio button shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
\endtable
\sa QPushButton, QToolButton, QCheckBox, {fowler}{GUI Design Handbook: Radio Button},
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 490dea0d2d..84be2d569b 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -77,9 +77,9 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qscrollarea-noscrollbars.png
- \o \inlineimage qscrollarea-onescrollbar.png
- \o \inlineimage qscrollarea-twoscrollbars.png
+ \li \inlineimage qscrollarea-noscrollbars.png
+ \li \inlineimage qscrollarea-onescrollbar.png
+ \li \inlineimage qscrollarea-twoscrollbars.png
\endtable
The scroll bars appearance depends on the currently set \l
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index cb3126e566..6ac5473f2e 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -83,21 +83,21 @@ QT_BEGIN_NAMESPACE
needs.
\table
- \row \o \image qscrollbar-picture.png
- \o Scroll bars typically include four separate controls: a slider,
+ \row \li \image qscrollbar-picture.png
+ \li Scroll bars typically include four separate controls: a slider,
scroll arrows, and a page control.
\list
- \o a. The slider provides a way to quickly go to any part of the
+ \li a. The slider provides a way to quickly go to any part of the
document, but does not support accurate navigation within large
documents.
- \o b. The scroll arrows are push buttons which can be used to accurately
+ \li b. The scroll arrows are push buttons which can be used to accurately
navigate to a particular place in a document. For a vertical scroll bar
connected to a text editor, these typically move the current position one
"line" up or down, and adjust the position of the slider by a small
amount. In editors and list boxes a "line" might mean one line of text;
in an image viewer it might mean 20 pixels.
- \o c. The page control is the area over which the slider is dragged (the
+ \li c. The page control is the area over which the slider is dragged (the
scroll bar's background). Clicking here moves the scroll bar towards
the click by one "page". This value is usually the same as the length of
the slider.
@@ -135,8 +135,8 @@ QT_BEGIN_NAMESPACE
value of 80. This would give us a scroll bar with five "pages".
\table
- \row \o \inlineimage qscrollbar-values.png
- \o The relationship between a document length, the range of values used
+ \row \li \inlineimage qscrollbar-values.png
+ \li The relationship between a document length, the range of values used
in a scroll bar, and the page step is simple in many common situations.
The scroll bar's range of values is determined by subtracting a
chosen page step from some value representing the length of the document.
@@ -153,18 +153,18 @@ QT_BEGIN_NAMESPACE
ScrollBar inherits a comprehensive set of signals from QAbstractSlider:
\list
- \o \l{QAbstractSlider::valueChanged()}{valueChanged()} is emitted when the
+ \li \l{QAbstractSlider::valueChanged()}{valueChanged()} is emitted when the
scroll bar's value has changed. The tracking() determines whether this
signal is emitted during user interaction.
- \o \l{QAbstractSlider::rangeChanged()}{rangeChanged()} is emitted when the
+ \li \l{QAbstractSlider::rangeChanged()}{rangeChanged()} is emitted when the
scroll bar's range of values has changed.
- \o \l{QAbstractSlider::sliderPressed()}{sliderPressed()} is emitted when
+ \li \l{QAbstractSlider::sliderPressed()}{sliderPressed()} is emitted when
the user starts to drag the slider.
- \o \l{QAbstractSlider::sliderMoved()}{sliderMoved()} is emitted when the user
+ \li \l{QAbstractSlider::sliderMoved()}{sliderMoved()} is emitted when the user
drags the slider.
- \o \l{QAbstractSlider::sliderReleased()}{sliderReleased()} is emitted when
+ \li \l{QAbstractSlider::sliderReleased()}{sliderReleased()} is emitted when
the user releases the slider.
- \o \l{QAbstractSlider::actionTriggered()}{actionTriggered()} is emitted
+ \li \l{QAbstractSlider::actionTriggered()}{actionTriggered()} is emitted
when the scroll bar is changed by user interaction or via the
\l{QAbstractSlider::triggerAction()}{triggerAction()} function.
\endlist
@@ -173,12 +173,12 @@ QT_BEGIN_NAMESPACE
default focusPolicy() of Qt::NoFocus. Use setFocusPolicy() to
enable keyboard interaction with the scroll bar:
\list
- \o Left/Right move a horizontal scroll bar by one single step.
- \o Up/Down move a vertical scroll bar by one single step.
- \o PageUp moves up one page.
- \o PageDown moves down one page.
- \o Home moves to the start (mininum).
- \o End moves to the end (maximum).
+ \li Left/Right move a horizontal scroll bar by one single step.
+ \li Up/Down move a vertical scroll bar by one single step.
+ \li PageUp moves up one page.
+ \li PageDown moves down one page.
+ \li Home moves to the start (mininum).
+ \li End moves to the end (maximum).
\endlist
The slider itself can be controlled by using the
@@ -190,12 +190,12 @@ QT_BEGIN_NAMESPACE
slider.
\table 100%
- \row \o \inlineimage macintosh-horizontalscrollbar.png Screenshot of a Macintosh style scroll bar
- \o A scroll bar shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windowsxp-horizontalscrollbar.png Screenshot of a Windows XP style scroll bar
- \o A scroll bar shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-horizontalscrollbar.png Screenshot of a Plastique style scroll bar
- \o A scroll bar shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage macintosh-horizontalscrollbar.png Screenshot of a Macintosh style scroll bar
+ \li A scroll bar shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage windowsxp-horizontalscrollbar.png Screenshot of a Windows XP style scroll bar
+ \li A scroll bar shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage plastique-horizontalscrollbar.png Screenshot of a Plastique style scroll bar
+ \li A scroll bar shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example}
diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp
index 09557a3c90..4a5269c110 100644
--- a/src/widgets/widgets/qsizegrip.cpp
+++ b/src/widgets/widgets/qsizegrip.cpp
@@ -195,8 +195,8 @@ Qt::Corner QSizeGripPrivate::corner() const
window is shown full screen or maximised.
\table 50%
- \row \o \inlineimage plastique-sizegrip.png Screenshot of a Plastique style size grip
- \o A size grip widget at the bottom-right corner of a main window, shown in the
+ \row \li \inlineimage plastique-sizegrip.png Screenshot of a Plastique style size grip
+ \li A size grip widget at the bottom-right corner of a main window, shown in the
\l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
index b05726c965..7f77bc9d03 100644
--- a/src/widgets/widgets/qslider.cpp
+++ b/src/widgets/widgets/qslider.cpp
@@ -225,17 +225,17 @@ QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
QSlider inherits a comprehensive set of signals:
\table
- \header \o Signal \o Description
- \row \o \l valueChanged()
- \o Emitted when the slider's value has changed. The tracking()
+ \header \li Signal \li Description
+ \row \li \l valueChanged()
+ \li Emitted when the slider's value has changed. The tracking()
determines whether this signal is emitted during user
interaction.
- \row \o \l sliderPressed()
- \o Emitted when the user starts to drag the slider.
- \row \o \l sliderMoved()
- \o Emitted when the user drags the slider.
- \row \o \l sliderReleased()
- \o Emitted when the user releases the slider.
+ \row \li \l sliderPressed()
+ \li Emitted when the user starts to drag the slider.
+ \row \li \l sliderMoved()
+ \li Emitted when the user drags the slider.
+ \row \li \l sliderReleased()
+ \li Emitted when the user releases the slider.
\endtable
QSlider only provides integer ranges. Note that although
@@ -246,21 +246,21 @@ QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
keyboard interface. The keyboard interface is the following:
\list
- \o Left/Right move a horizontal slider by one single step.
- \o Up/Down move a vertical slider by one single step.
- \o PageUp moves up one page.
- \o PageDown moves down one page.
- \o Home moves to the start (mininum).
- \o End moves to the end (maximum).
+ \li Left/Right move a horizontal slider by one single step.
+ \li Up/Down move a vertical slider by one single step.
+ \li PageUp moves up one page.
+ \li PageDown moves down one page.
+ \li Home moves to the start (mininum).
+ \li End moves to the end (maximum).
\endlist
\table 100%
- \row \o \inlineimage macintosh-slider.png Screenshot of a Macintosh slider
- \o A slider shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windows-slider.png Screenshot of a Windows XP slider
- \o A slider shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-slider.png Screenshot of a Plastique slider
- \o A slider shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage macintosh-slider.png Screenshot of a Macintosh slider
+ \li A slider shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage windows-slider.png Screenshot of a Windows XP slider
+ \li A slider shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage plastique-slider.png Screenshot of a Plastique slider
+ \li A slider shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
\endtable
\sa QScrollBar, QSpinBox, QDial, {fowler}{GUI Design Handbook: Slider}, {Sliders Example}
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 3038d8e30c..7dcaead2f4 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -152,12 +152,12 @@ public:
setSpecialValueText() for how to do this with QSpinBox.
\table 100%
- \row \o \inlineimage windowsxp-spinbox.png Screenshot of a Windows XP spin box
- \o A spin box shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-spinbox.png Screenshot of a Plastique spin box
- \o A spin box shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \row \o \inlineimage macintosh-spinbox.png Screenshot of a Macintosh spin box
- \o A spin box shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \li \inlineimage windowsxp-spinbox.png Screenshot of a Windows XP spin box
+ \li A spin box shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \li \inlineimage plastique-spinbox.png Screenshot of a Plastique spin box
+ \li A spin box shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row \li \inlineimage macintosh-spinbox.png Screenshot of a Macintosh spin box
+ \li A spin box shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
\endtable
\section1 Subclassing QSpinBox
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 3c88090eb6..5406f5dcf5 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -190,7 +190,7 @@ int QStackedWidget::insertWidget(int index, QWidget *widget)
not deleted but simply removed from the stacked layout, causing it
to be hidden.
- \bold{Note:} Ownership of \a widget reverts to the application.
+ \b{Note:} Ownership of \a widget reverts to the application.
\sa addWidget(), insertWidget(), currentWidget()
*/
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 9f170626da..4b9242499c 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -165,12 +165,12 @@ QRect QStatusBarPrivate::messageRect() const
Each status indicator falls into one of three categories:
\list
- \o \e Temporary - briefly occupies most of the status bar. Used
+ \li \e Temporary - briefly occupies most of the status bar. Used
to explain tool tip texts or menu entries, for example.
- \o \e Normal - occupies part of the status bar and may be hidden
+ \li \e Normal - occupies part of the status bar and may be hidden
by temporary messages. Used to display the page and line
number in a word processor, for example.
- \o \e Permanent - is never hidden. Used for important mode
+ \li \e Permanent - is never hidden. Used for important mode
indications, for example, some applications put a Caps Lock
indicator in the status bar.
\endlist
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 580aea10b9..ca94854d11 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -252,21 +252,21 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
tab:
\list
- \i tabSizeHint() calcuates the size of a tab.
- \i tabInserted() notifies that a new tab was added.
- \i tabRemoved() notifies that a tab was removed.
- \i tabLayoutChange() notifies that the tabs have been re-laid out.
- \i paintEvent() paints all tabs.
+ \li tabSizeHint() calcuates the size of a tab.
+ \li tabInserted() notifies that a new tab was added.
+ \li tabRemoved() notifies that a tab was removed.
+ \li tabLayoutChange() notifies that the tabs have been re-laid out.
+ \li paintEvent() paints all tabs.
\endlist
For subclasses, you might also need the tabRect() functions which
returns the visual geometry of a single tab.
\table 100%
- \row \o \inlineimage plastique-tabbar.png Screenshot of a Plastique style tab bar
- \o A tab bar shown in the Plastique widget style.
- \row \o \inlineimage plastique-tabbar-truncated.png Screenshot of a truncated Plastique tab bar
- \o A truncated tab bar shown in the Plastique widget style.
+ \row \li \inlineimage plastique-tabbar.png Screenshot of a Plastique style tab bar
+ \li A tab bar shown in the Plastique widget style.
+ \row \li \inlineimage plastique-tabbar-truncated.png Screenshot of a truncated Plastique tab bar
+ \li A truncated tab bar shown in the Plastique widget style.
\endtable
\sa QTabWidget
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 612d51826c..505287512e 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -77,12 +77,12 @@ QT_BEGIN_NAMESPACE
The normal way to use QTabWidget is to do the following:
\list 1
- \i Create a QTabWidget.
- \i Create a QWidget for each of the pages in the tab dialog, but
+ \li Create a QTabWidget.
+ \li Create a QWidget for each of the pages in the tab dialog, but
do not specify parent widgets for them.
- \i Insert child widgets into the page widget, using layouts to
+ \li Insert child widgets into the page widget, using layouts to
position them as normal.
- \i Call addTab() or insertTab() to put the page widgets into the
+ \li Call addTab() or insertTab() to put the page widgets into the
tab widget, giving each tab a suitable label with an optional
keyboard shortcut.
\endlist
@@ -120,12 +120,12 @@ QT_BEGIN_NAMESPACE
area, organizing the individual pages).
\table 100%
- \row \o \inlineimage windowsxp-tabwidget.png Screenshot of a Windows XP style tab widget
- \o \inlineimage macintosh-tabwidget.png Screenshot of a Macintosh style tab widget
- \o \inlineimage plastique-tabwidget.png Screenshot of a Plastique style tab widget
- \row \o A Windows XP style tab widget.
- \o A Macintosh style tab widget.
- \o A Plastique style tab widget.
+ \row \li \inlineimage windowsxp-tabwidget.png Screenshot of a Windows XP style tab widget
+ \li \inlineimage macintosh-tabwidget.png Screenshot of a Macintosh style tab widget
+ \li \inlineimage plastique-tabwidget.png Screenshot of a Plastique style tab widget
+ \row \li A Windows XP style tab widget.
+ \li A Macintosh style tab widget.
+ \li A Plastique style tab widget.
\endtable
\sa QTabBar, QStackedWidget, QToolBox, {Tab Dialog Example}
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index d9229c12e8..050730ec2a 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -902,10 +902,10 @@ void QTextBrowser::home()
/*!
The event \a ev is used to provide the following keyboard shortcuts:
\table
- \header \i Keypress \i Action
- \row \i Alt+Left Arrow \i \l backward()
- \row \i Alt+Right Arrow \i \l forward()
- \row \i Alt+Up Arrow \i \l home()
+ \header \li Keypress \li Action
+ \row \li Alt+Left Arrow \li \l backward()
+ \row \li Alt+Right Arrow \li \l forward()
+ \row \li Alt+Up Arrow \li \l home()
\endtable
*/
void QTextBrowser::keyPressEvent(QKeyEvent *ev)
@@ -1068,10 +1068,10 @@ void QTextBrowser::paintEvent(QPaintEvent *e)
depending on the resource type:
\table
- \header \i ResourceType \i QVariant::Type
- \row \i QTextDocument::HtmlResource \i QString or QByteArray
- \row \i QTextDocument::ImageResource \i QImage, QPixmap or QByteArray
- \row \i QTextDocument::StyleSheetResource \i QString or QByteArray
+ \header \li ResourceType \li QVariant::Type
+ \row \li QTextDocument::HtmlResource \li QString or QByteArray
+ \row \li QTextDocument::ImageResource \li QImage, QPixmap or QByteArray
+ \row \li QTextDocument::StyleSheetResource \li QString or QByteArray
\endtable
*/
QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)
@@ -1146,10 +1146,10 @@ void QTextBrowser::clearHistory()
Returns the url of the HistoryItem.
\table
- \header \i Input \i Return
- \row \i \a{i} < 0 \i \l backward() history
- \row \i\a{i} == 0 \i current, see QTextBrowser::source()
- \row \i \a{i} > 0 \i \l forward() history
+ \header \li Input \li Return
+ \row \li \a{i} < 0 \li \l backward() history
+ \row \li\a{i} == 0 \li current, see QTextBrowser::source()
+ \row \li \a{i} > 0 \li \l forward() history
\endtable
\since 4.4
@@ -1164,10 +1164,10 @@ QUrl QTextBrowser::historyUrl(int i) const
Returns the documentTitle() of the HistoryItem.
\table
- \header \i Input \i Return
- \row \i \a{i} < 0 \i \l backward() history
- \row \i \a{i} == 0 \i current, see QTextBrowser::source()
- \row \i \a{i} > 0 \i \l forward() history
+ \header \li Input \li Return
+ \row \li \a{i} < 0 \li \l backward() history
+ \row \li \a{i} == 0 \li current, see QTextBrowser::source()
+ \row \li \a{i} > 0 \li \l forward() history
\endtable
\snippet doc/src/snippets/code/src_gui_widgets_qtextbrowser.cpp 0
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index d0065aacb9..198d101dbf 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -412,19 +412,19 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
When QTextEdit is used read-only the key bindings are limited to
navigation, and text may only be selected with the mouse:
\table
- \header \i Keypresses \i Action
- \row \i Up \i Moves one line up.
- \row \i Down \i Moves one line down.
- \row \i Left \i Moves one character to the left.
- \row \i Right \i Moves one character to the right.
- \row \i PageUp \i Moves one (viewport) page up.
- \row \i PageDown \i Moves one (viewport) page down.
- \row \i Home \i Moves to the beginning of the text.
- \row \i End \i Moves to the end of the text.
- \row \i Alt+Wheel
- \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
- \row \i Ctrl+A \i Selects all text.
+ \header \li Keypresses \li Action
+ \row \li Up \li Moves one line up.
+ \row \li Down \li Moves one line down.
+ \row \li Left \li Moves one character to the left.
+ \row \li Right \li Moves one character to the right.
+ \row \li PageUp \li Moves one (viewport) page up.
+ \row \li PageDown \li Moves one (viewport) page down.
+ \row \li Home \li Moves to the beginning of the text.
+ \row \li End \li Moves to the end of the text.
+ \row \li Alt+Wheel
+ \li Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \li Ctrl+Wheel \li Zooms the text.
+ \row \li Ctrl+A \li Selects all text.
\endtable
The text edit may be able to provide some meta-information. For
@@ -486,31 +486,31 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
The list of key bindings which are implemented for editing:
\table
- \header \i Keypresses \i Action
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+C \i Copy the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into text edit.
- \row \i Shift+Insert \i Pastes the clipboard text into text edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last operation.
- \row \i Left \i Moves the cursor one character to the left.
- \row \i Ctrl+Left \i Moves the cursor one word to the left.
- \row \i Right \i Moves the cursor one character to the right.
- \row \i Ctrl+Right \i Moves the cursor one word to the right.
- \row \i Up \i Moves the cursor one line up.
- \row \i Down \i Moves the cursor one line down.
- \row \i PageUp \i Moves the cursor one page up.
- \row \i PageDown \i Moves the cursor one page down.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Ctrl+End \i Moves the cursor to the end of the text.
- \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \header \li Keypresses \li Action
+ \row \li Backspace \li Deletes the character to the left of the cursor.
+ \row \li Delete \li Deletes the character to the right of the cursor.
+ \row \li Ctrl+C \li Copy the selected text to the clipboard.
+ \row \li Ctrl+Insert \li Copy the selected text to the clipboard.
+ \row \li Ctrl+K \li Deletes to the end of the line.
+ \row \li Ctrl+V \li Pastes the clipboard text into text edit.
+ \row \li Shift+Insert \li Pastes the clipboard text into text edit.
+ \row \li Ctrl+X \li Deletes the selected text and copies it to the clipboard.
+ \row \li Shift+Delete \li Deletes the selected text and copies it to the clipboard.
+ \row \li Ctrl+Z \li Undoes the last operation.
+ \row \li Ctrl+Y \li Redoes the last operation.
+ \row \li Left \li Moves the cursor one character to the left.
+ \row \li Ctrl+Left \li Moves the cursor one word to the left.
+ \row \li Right \li Moves the cursor one character to the right.
+ \row \li Ctrl+Right \li Moves the cursor one word to the right.
+ \row \li Up \li Moves the cursor one line up.
+ \row \li Down \li Moves the cursor one line down.
+ \row \li PageUp \li Moves the cursor one page up.
+ \row \li PageDown \li Moves the cursor one page down.
+ \row \li Home \li Moves the cursor to the beginning of the line.
+ \row \li Ctrl+Home \li Moves the cursor to the beginning of the text.
+ \row \li End \li Moves the cursor to the end of the line.
+ \row \li Ctrl+End \li Moves the cursor to the end of the text.
+ \row \li Alt+Wheel \li Scrolls the page horizontally (the Wheel is the mouse wheel).
\endtable
To select (mark) text hold down the Shift key whilst pressing one
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index 015419a879..68a4f20fb6 100644
--- a/src/widgets/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
@@ -159,8 +159,8 @@ bool QToolButtonPrivate::hasMenu() const
adjust it with setPopupDelay().
\table 100%
- \row \o \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons
- \row \o Qt Assistant's toolbar contains tool buttons that are associated
+ \row \li \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons
+ \row \li Qt Assistant's toolbar contains tool buttons that are associated
with actions used in other parts of the main window.
\endtable
diff --git a/src/widgets/widgets/qwidgetanimator_p.h b/src/widgets/widgets/qwidgetanimator_p.h
index e2054401d6..82f81a704f 100644
--- a/src/widgets/widgets/qwidgetanimator_p.h
+++ b/src/widgets/widgets/qwidgetanimator_p.h
@@ -54,7 +54,7 @@
//
#include <qobject.h>
-#include <qmap.h>
+#include <qhash.h>
QT_BEGIN_NAMESPACE
@@ -79,7 +79,7 @@ private Q_SLOTS:
#endif
private:
- typedef QMap<QWidget*, QPropertyAnimation*> AnimationMap;
+ typedef QHash<QWidget*, QPropertyAnimation*> AnimationMap;
AnimationMap m_animation_map;
QMainWindowLayout *m_mainWindowLayout;
};
diff --git a/src/widgets/widgets/qworkspace.cpp b/src/widgets/widgets/qworkspace.cpp
index 5cc8e363f1..36c589be1c 100644
--- a/src/widgets/widgets/qworkspace.cpp
+++ b/src/widgets/widgets/qworkspace.cpp
@@ -878,8 +878,8 @@ QSize QWorkspaceTitleBar::sizeHint() const
connect menu entries to them.
\table
- \row \o \inlineimage mdi-cascade.png
- \o \inlineimage mdi-tile.png
+ \row \li \inlineimage mdi-cascade.png
+ \li \inlineimage mdi-tile.png
\endtable
If you want your users to be able to work with child windows
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index c503302fbb..766ca51ec3 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -970,8 +970,8 @@ QDomImplementation::~QDomImplementation()
The currently supported features and their versions:
\table
- \header \i Feature \i Version
- \row \i XML \i 1.0
+ \header \li Feature \li Version
+ \row \li XML \li 1.0
\endtable
*/
bool QDomImplementation::hasFeature(const QString& feature, const QString& version) const
@@ -2098,22 +2098,22 @@ QDomNode::~QDomNode()
The meaning of the name depends on the subclass:
\table
- \header \i Name \i Meaning
- \row \i QDomAttr \i The name of the attribute
- \row \i QDomCDATASection \i The string "#cdata-section"
- \row \i QDomComment \i The string "#comment"
- \row \i QDomDocument \i The string "#document"
- \row \i QDomDocumentFragment \i The string "#document-fragment"
- \row \i QDomDocumentType \i The name of the document type
- \row \i QDomElement \i The tag name
- \row \i QDomEntity \i The name of the entity
- \row \i QDomEntityReference \i The name of the referenced entity
- \row \i QDomNotation \i The name of the notation
- \row \i QDomProcessingInstruction \i The target of the processing instruction
- \row \i QDomText \i The string "#text"
+ \header \li Name \li Meaning
+ \row \li QDomAttr \li The name of the attribute
+ \row \li QDomCDATASection \li The string "#cdata-section"
+ \row \li QDomComment \li The string "#comment"
+ \row \li QDomDocument \li The string "#document"
+ \row \li QDomDocumentFragment \li The string "#document-fragment"
+ \row \li QDomDocumentType \li The name of the document type
+ \row \li QDomElement \li The tag name
+ \row \li QDomEntity \li The name of the entity
+ \row \li QDomEntityReference \li The name of the referenced entity
+ \row \li QDomNotation \li The name of the notation
+ \row \li QDomProcessingInstruction \li The target of the processing instruction
+ \row \li QDomText \li The string "#text"
\endtable
- \bold{Note:} This function does not take the presence of namespaces into account
+ \b{Note:} This function does not take the presence of namespaces into account
when processing the names of element and attribute nodes. As a result, the
returned name can contain any namespace prefix that may be present.
To obtain the node name of an element or attribute, use localName(); to
@@ -2136,12 +2136,12 @@ QString QDomNode::nodeName() const
The meaning of the value depends on the subclass:
\table
- \header \i Name \i Meaning
- \row \i QDomAttr \i The attribute value
- \row \i QDomCDATASection \i The content of the CDATA section
- \row \i QDomComment \i The comment
- \row \i QDomProcessingInstruction \i The data of the processing instruction
- \row \i QDomText \i The text
+ \header \li Name \li Meaning
+ \row \li QDomAttr \li The attribute value
+ \row \li QDomCDATASection \li The content of the CDATA section
+ \row \li QDomComment \li The comment
+ \row \li QDomProcessingInstruction \li The data of the processing instruction
+ \row \li QDomText \li The text
\endtable
All the other subclasses do not have a node value and will return
@@ -3191,11 +3191,11 @@ bool QDomNamedNodeMapPrivate::containsNS(const QString& nsURI, const QString & l
The QDomNamedNodeMap is used in three places:
\list 1
- \i QDomDocumentType::entities() returns a map of all entities
+ \li QDomDocumentType::entities() returns a map of all entities
described in the DTD.
- \i QDomDocumentType::notations() returns a map of all notations
+ \li QDomDocumentType::notations() returns a map of all notations
described in the DTD.
- \i QDomNode::attributes() returns a map of all attributes of an
+ \li QDomNode::attributes() returns a map of all attributes of an
element.
\endlist
@@ -3427,7 +3427,7 @@ int QDomNamedNodeMap::length() const
Returns true if the map contains a node called \a name; otherwise
returns false.
- \bold{Note:} This function does not take the presence of namespaces into account.
+ \b{Note:} This function does not take the presence of namespaces into account.
Use namedItemNS() to test whether the map contains a node with a specific namespace
URI and name.
*/
@@ -4950,7 +4950,7 @@ QDomNodeList QDomElement::elementsByTagName(const QString& tagname) const
Returns true if this element has an attribute called \a name;
otherwise returns false.
- \bold{Note:} This function does not take the presence of namespaces
+ \b{Note:} This function does not take the presence of namespaces
into account. As a result, the specified name will be tested
against fully-qualified attribute names that include any namespace
prefixes that may be present.
@@ -6692,17 +6692,17 @@ bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QSt
Entity references are handled as follows:
\list
- \o References to internal general entities and character entities occurring in the
+ \li References to internal general entities and character entities occurring in the
content are included. The result is a QDomText node with the references replaced
by their corresponding entity values.
- \o References to parameter entities occurring in the internal subset are included.
+ \li References to parameter entities occurring in the internal subset are included.
The result is a QDomDocumentType node which contains entity and notation declarations
with the references replaced by their corresponding entity values.
- \o Any general parsed entity reference which is not defined in the internal subset and
+ \li Any general parsed entity reference which is not defined in the internal subset and
which occurs in the content is represented as a QDomEntityReference node.
- \o Any parsed entity reference which is not defined in the internal subset and which
+ \li Any parsed entity reference which is not defined in the internal subset and which
occurs outside of the content is replaced with an empty string.
- \o Any unparsed entity reference is replaced with an empty string.
+ \li Any unparsed entity reference is replaced with an empty string.
\endlist
\sa QDomNode::namespaceURI() QDomNode::localName()
@@ -7039,46 +7039,46 @@ QDomNodeList QDomDocument::elementsByTagName(const QString& tagname) const
The behavior of this function is slightly different depending on
the node types:
\table
- \header \i Node Type \i Behavior
- \row \i QDomAttr
- \i The owner element is set to 0 and the specified flag is
+ \header \li Node Type \li Behavior
+ \row \li QDomAttr
+ \li The owner element is set to 0 and the specified flag is
set to true in the generated attribute. The whole subtree
of \a importedNode is always imported for attribute nodes:
\a deep has no effect.
- \row \i QDomDocument
- \i Document nodes cannot be imported.
- \row \i QDomDocumentFragment
- \i If \a deep is true, this function imports the whole
+ \row \li QDomDocument
+ \li Document nodes cannot be imported.
+ \row \li QDomDocumentFragment
+ \li If \a deep is true, this function imports the whole
document fragment; otherwise it only generates an empty
document fragment.
- \row \i QDomDocumentType
- \i Document type nodes cannot be imported.
- \row \i QDomElement
- \i Attributes for which QDomAttr::specified() is true are
+ \row \li QDomDocumentType
+ \li Document type nodes cannot be imported.
+ \row \li QDomElement
+ \li Attributes for which QDomAttr::specified() is true are
also imported, other attributes are not imported. If \a
deep is true, this function also imports the subtree of \a
importedNode; otherwise it imports only the element node
(and some attributes, see above).
- \row \i QDomEntity
- \i Entity nodes can be imported, but at the moment there is
+ \row \li QDomEntity
+ \li Entity nodes can be imported, but at the moment there is
no way to use them since the document type is read-only in
DOM level 2.
- \row \i QDomEntityReference
- \i Descendants of entity reference nodes are never imported:
+ \row \li QDomEntityReference
+ \li Descendants of entity reference nodes are never imported:
\a deep has no effect.
- \row \i QDomNotation
- \i Notation nodes can be imported, but at the moment there is
+ \row \li QDomNotation
+ \li Notation nodes can be imported, but at the moment there is
no way to use them since the document type is read-only in
DOM level 2.
- \row \i QDomProcessingInstruction
- \i The target and value of the processing instruction is
+ \row \li QDomProcessingInstruction
+ \li The target and value of the processing instruction is
copied to the new node.
- \row \i QDomText
- \i The text is copied to the new node.
- \row \i QDomCDATASection
- \i The text is copied to the new node.
- \row \i QDomComment
- \i The text is copied to the new node.
+ \row \li QDomText
+ \li The text is copied to the new node.
+ \row \li QDomCDATASection
+ \li The text is copied to the new node.
+ \row \li QDomComment
+ \li The text is copied to the new node.
\endtable
\sa QDomElement::setAttribute() QDomNode::insertBefore()
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 75e2fdb2e7..c2205edb40 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -516,29 +516,29 @@ private:
\list
- \o "no error occurred"
- \o "error triggered by consumer"
- \o "unexpected end of file"
- \o "more than one document type definition"
- \o "error occurred while parsing element"
- \o "tag mismatch"
- \o "error occurred while parsing content"
- \o "unexpected character"
- \o "invalid name for processing instruction"
- \o "version expected while reading the XML declaration"
- \o "wrong value for standalone declaration"
- \o "encoding declaration or standalone declaration expected while reading the XML declaration"
- \o "standalone declaration expected while reading the XML declaration"
- \o "error occurred while parsing document type definition"
- \o "letter is expected"
- \o "error occurred while parsing comment"
- \o "error occurred while parsing reference"
- \o "internal general entity reference not allowed in DTD"
- \o "external parsed general entity reference not allowed in attribute value"
- \o "external parsed general entity reference not allowed in DTD"
- \o "unparsed entity reference n wrong context"
- \o "recursive entities"
- \o "error in the text declaration of an external entity"
+ \li "no error occurred"
+ \li "error triggered by consumer"
+ \li "unexpected end of file"
+ \li "more than one document type definition"
+ \li "error occurred while parsing element"
+ \li "tag mismatch"
+ \li "error occurred while parsing content"
+ \li "unexpected character"
+ \li "invalid name for processing instruction"
+ \li "version expected while reading the XML declaration"
+ \li "wrong value for standalone declaration"
+ \li "encoding declaration or standalone declaration expected while reading the XML declaration"
+ \li "standalone declaration expected while reading the XML declaration"
+ \li "error occurred while parsing document type definition"
+ \li "letter is expected"
+ \li "error occurred while parsing comment"
+ \li "error occurred while parsing reference"
+ \li "internal general entity reference not allowed in DTD"
+ \li "external parsed general entity reference not allowed in attribute value"
+ \li "external parsed general entity reference not allowed in DTD"
+ \li "unparsed entity reference n wrong context"
+ \li "recursive entities"
+ \li "error in the text declaration of an external entity"
\endlist
Note that, if you want to display these error messages to your
@@ -3157,24 +3157,24 @@ bool QXmlSimpleReader::feature(const QString& name, bool *ok) const
The \a name parameter must be one of the following strings:
\table
- \header \i Feature \i Default \i Notes
- \row \i \e http://xml.org/sax/features/namespaces
- \i true
- \i If enabled, namespaces are reported to the content handler.
- \row \i \e http://xml.org/sax/features/namespace-prefixes
- \i false
- \i If enabled, the original prefixed names
+ \header \li Feature \li Default \li Notes
+ \row \li \e http://xml.org/sax/features/namespaces
+ \li true
+ \li If enabled, namespaces are reported to the content handler.
+ \row \li \e http://xml.org/sax/features/namespace-prefixes
+ \li false
+ \li If enabled, the original prefixed names
and attributes used for namespace declarations are
reported.
- \row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
- \i true
- \i If enabled, CharData that consist of
+ \row \li \e http://trolltech.com/xml/features/report-whitespace-only-CharData
+ \li true
+ \li If enabled, CharData that consist of
only whitespace characters are reported
using QXmlContentHandler::characters(). If disabled, whitespace is silently
discarded.
- \row \i \e http://trolltech.com/xml/features/report-start-end-entity
- \i false
- \i If enabled, the parser reports
+ \row \li \e http://trolltech.com/xml/features/report-start-end-entity
+ \li false
+ \li If enabled, the parser reports
QXmlContentHandler::startEntity() and
QXmlContentHandler::endEntity() events, so character data
might be reported in chunks.
diff --git a/tests/auto/corelib/global/qlogging/test/test.pro b/tests/auto/corelib/global/qlogging/test/test.pro
index 6e4939ffc9..6e9b86d753 100644
--- a/tests/auto/corelib/global/qlogging/test/test.pro
+++ b/tests/auto/corelib/global/qlogging/test/test.pro
@@ -2,3 +2,6 @@ CONFIG += testcase parallel_test
TARGET = ../tst_qlogging
QT = core testlib
SOURCES = ../tst_qlogging.cpp
+
+load(testcase) # for target.path and installTestHelperApp()
+installTestHelperApp("../app/app",app,app)
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 04967d8313..b7fc366a39 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -1214,7 +1214,8 @@ void tst_QDir::remove()
f.close();
QDir dir;
QVERIFY(dir.remove("remove-test"));
- QVERIFY(!dir.remove("/remove-test"));
+ // Test that the file just removed is gone
+ QVERIFY(!dir.remove("remove-test"));
QTest::ignoreMessage(QtWarningMsg, "QDir::remove: Empty or null file name");
QVERIFY(!dir.remove(""));
}
@@ -1231,8 +1232,14 @@ void tst_QDir::rename()
QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed"));
#elif !defined(Q_OS_WIN)
// on windows this is possible - maybe make the test a bit better
+#ifdef Q_OS_UNIX
+ // not valid if run as root so skip if needed
+ if (::getuid() != 0)
+ QVERIFY(!dir.rename("rename-test", "/rename-test-renamed"));
+#else
QVERIFY(!dir.rename("rename-test", "/rename-test-renamed"));
#endif
+#endif
QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)");
QVERIFY(!dir.rename("rename-test", ""));
QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)");
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
index 815401ce1e..ba68167a6f 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
@@ -7,6 +7,6 @@ QT = core testlib concurrent
SOURCES = tst_qmimedatabase-cache.cpp
HEADERS = ../tst_qmimedatabase.h
-DEFINES += SRCDIR='"\\"$$PWD/../\\""'
+DEFINES += CORE_SOURCES='"\\"$$QT.core.sources\\""'
*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
index 205331d4dd..5ef04dc01d 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
@@ -47,10 +47,9 @@
#include "../tst_qmimedatabase.cpp"
-tst_QMimeDatabase::tst_QMimeDatabase()
+void tst_QMimeDatabase::init()
{
- QDir here = QDir::currentPath();
- const QString tempMime = here.absolutePath() + QString::fromLatin1("/mime");
- runUpdateMimeDatabase(tempMime);
- QVERIFY(QFile::exists(tempMime + QString::fromLatin1("/mime.cache")));
+ const QString mimeDirName = m_globalXdgDir + QStringLiteral("/mime");
+ runUpdateMimeDatabase(mimeDirName);
+ QVERIFY(QFile::exists(mimeDirName + QStringLiteral("/mime.cache")));
}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
index ac7515f781..4c00e84fc1 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
@@ -9,6 +9,6 @@ CONFIG += depend_includepath
SOURCES += tst_qmimedatabase-xml.cpp
HEADERS += ../tst_qmimedatabase.h
-DEFINES += SRCDIR='"\\"$$PWD/../\\""'
+DEFINES += CORE_SOURCES='"\\"$$QT.core.sources\\""'
*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
index 13ca372290..30c7677198 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
@@ -40,10 +40,8 @@
****************************************************************************/
#include "../tst_qmimedatabase.h"
-#include <QDebug>
-#include <QDir>
-tst_QMimeDatabase::tst_QMimeDatabase()
+void tst_QMimeDatabase::init()
{
qputenv("QT_NO_MIME_CACHE", "1");
}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
index 876b4377dd..1ff5546e5c 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = qmimedatabase-xml
-unix: SUBDIRS += qmimedatabase-cache
+unix:!mac: SUBDIRS += qmimedatabase-cache
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 858f977a72..63adcadb86 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -44,49 +44,85 @@
#include "qstandardpaths.h"
#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextStream>
#include <QtConcurrent/QtConcurrentRun>
#include <QtConcurrent/QFuture>
#include <QtTest/QtTest>
+static const char yastFileName[] ="yast2-metapackage-handler-mimetypes.xml";
+
void initializeLang()
{
qputenv("LC_ALL", "");
qputenv("LANG", "en_US");
+ QCoreApplication::setApplicationName("tst_qmimedatabase"); // temporary directory pattern
+}
+
+static inline QString testSuiteWarning()
+{
+
+ QString result;
+ QTextStream str(&result);
+ str << "\nCannot find the shared-mime-info test suite\nstarting from: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+ "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-0.zip\n"
+ "unzip Release-1-0.zip\n";
+#ifdef Q_OS_WIN
+ str << "mkdir testfiles\nxcopy /s Release-1-0\\tests testfiles\n";
+#else
+ str << "ln -s Release-1-0/tests testfiles\n";
+#endif
+ return result;
}
// Set LANG before QCoreApplication is created
Q_CONSTRUCTOR_FUNCTION(initializeLang)
+tst_QMimeDatabase::tst_QMimeDatabase()
+{
+}
+
void tst_QMimeDatabase::initTestCase()
{
+ QVERIFY(m_temporaryDir.isValid());
+
// Create a "global" and a "local" XDG data dir, right here.
// The local dir will be empty initially, while the global dir will contain a copy of freedesktop.org.xml
- QDir here = QDir::currentPath();
+ const QDir here = QDir(m_temporaryDir.path());
- qputenv("XDG_DATA_DIRS", QFile::encodeName(here.absolutePath()));
- QDir(here.absolutePath() + "/mime").removeRecursively();
- here.mkpath(QString::fromLatin1("mime/packages"));
+ m_globalXdgDir = m_temporaryDir.path() + QStringLiteral("/global");
+ m_localXdgDir = m_temporaryDir.path() + QStringLiteral("/local");
- QFile xml(QFile::decodeName(SRCDIR "../../../src/mimetypes/mime/packages/freedesktop.org.xml"));
- const QString mimeDir = here.absolutePath() + QLatin1String("/mime");
- xml.copy(mimeDir + QLatin1String("/packages/freedesktop.org.xml"));
+ const QString globalPackageDir = m_globalXdgDir + QStringLiteral("/mime/packages");
+ QVERIFY(here.mkpath(globalPackageDir) && here.mkpath(m_localXdgDir));
- m_dataHome = here.absolutePath() + QLatin1String("/../datahome");
- qputenv("XDG_DATA_HOME", QFile::encodeName(m_dataHome));
- //qDebug() << "XDG_DATA_HOME=" << m_dataHome;
+ qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalXdgDir));
+ qputenv("XDG_DATA_HOME", QFile::encodeName(m_localXdgDir));
+ qDebug() << "\nLocal XDG_DATA_HOME: " << m_localXdgDir
+ << "\nGlobal XDG_DATA_DIRS: " << m_globalXdgDir;
- // Make sure we start clean
- cleanupTestCase();
-}
+ const QString freeDesktopXml = QStringLiteral("freedesktop.org.xml");
+ const QString xmlFileName = QLatin1String(CORE_SOURCES)
+ + QStringLiteral("/mimetypes/mime/packages/")
+ + freeDesktopXml;
+ QVERIFY2(QFileInfo(xmlFileName).exists(), qPrintable(xmlFileName + QStringLiteral(" does not exist")));
+ QFile xml(xmlFileName);
+ QVERIFY(xml.copy(globalPackageDir + '/' + freeDesktopXml));
-void tst_QMimeDatabase::cleanupTestCase()
-{
- QDir here = QDir::currentPath();
- here.remove(QString::fromLatin1("mime/packages/yast2-metapackage-handler-mimetypes.xml"));
+ m_testSuite = QFINDTESTDATA("testfiles");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+ m_yastMimeTypes = QFINDTESTDATA(yastFileName);
+ QVERIFY2(!m_yastMimeTypes.isEmpty(),
+ qPrintable(QString::fromLatin1("Cannot find '%1' starting from '%2'").
+ arg(yastFileName, QDir::currentPath())));
- QDir(m_dataHome).removeRecursively();
+ init();
}
void tst_QMimeDatabase::mimeTypeForName()
@@ -173,6 +209,19 @@ void tst_QMimeDatabase::mimeTypeForFileName_data()
QTest::newRow("doesn't exist but has known extension") << "IDontExist.txt" << "text/plain";
}
+static inline QByteArray msgMimeTypeForFileNameFailed(const QList<QMimeType> &actual,
+ const QString &expected)
+{
+ QByteArray result = "Actual (";
+ foreach (const QMimeType &m, actual) {
+ result += m.name().toLocal8Bit();
+ result += ' ';
+ }
+ result += ") , expected: ";
+ result += expected.toLocal8Bit();
+ return result;
+}
+
void tst_QMimeDatabase::mimeTypeForFileName()
{
QFETCH(QString, fileName);
@@ -186,8 +235,8 @@ void tst_QMimeDatabase::mimeTypeForFileName()
if (expectedMimeType == "application/octet-stream") {
QVERIFY(mimes.isEmpty());
} else {
- QVERIFY(!mimes.isEmpty());
- QCOMPARE(mimes.count(), 1);
+ QVERIFY2(!mimes.isEmpty(), msgMimeTypeForFileNameFailed(mimes, expectedMimeType).constData());
+ QVERIFY2(mimes.count() == 1, msgMimeTypeForFileNameFailed(mimes, expectedMimeType).constData());
QCOMPARE(mimes.first().name(), expectedMimeType);
}
}
@@ -549,20 +598,14 @@ void tst_QMimeDatabase::findByFileName_data()
QTest::addColumn<QString>("mimeTypeName");
QTest::addColumn<QString>("xFail");
- QString prefix = QLatin1String(SRCDIR "testfiles/");
-
- QFile f(prefix + QLatin1String("list"));
- if (!f.open(QIODevice::ReadOnly)) {
- const QString warning = QString::fromLatin1(
- "Please download the shared-mime-info test suite:\n"
- "cd tests/auto/corelib/mimetypes/qmimedatabase\n"
- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-0.zip\n"
- "unzip Release-1-0.zip\n"
- "ln -s Release-1-0/tests testfiles\n"
- );
- qWarning() << warning;
+ if (m_testSuite.isEmpty())
QSKIP("shared-mime-info test suite not available.");
- }
+
+ const QString prefix = m_testSuite + QLatin1Char('/');
+ const QString fileName = prefix + QLatin1String("list");
+ QFile f(fileName);
+ QVERIFY2(f.open(QIODevice::ReadOnly|QIODevice::Text),
+ qPrintable(QString::fromLatin1("Cannot open %1: %2").arg(fileName, f.errorString())));
QByteArray line(1024, Qt::Uninitialized);
@@ -582,7 +625,9 @@ void tst_QMimeDatabase::findByFileName_data()
if (list.size() >= 3)
xFail = list.at(2);
- QTest::newRow(filePath.toLatin1().constData()) << QString(prefix + filePath) << mimeTypeType << xFail;
+ QTest::newRow(filePath.toLatin1().constData())
+ << QString(prefix + filePath)
+ << mimeTypeType << xFail;
}
}
@@ -676,6 +721,9 @@ void tst_QMimeDatabase::findByFile_data()
findByFileName_data();
}
+// Note: this test fails on "testcompress.z" when using a shared-mime-info older than 1.0.
+// This because of commit 0f9a506069c in shared-mime-info, which fixed the writing of
+// case-insensitive patterns into mime.cache.
void tst_QMimeDatabase::findByFile()
{
QFETCH(QString, filePath);
@@ -717,13 +765,21 @@ void tst_QMimeDatabase::fromThreads()
static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method?
{
- const QString umd = QStandardPaths::findExecutable(QString::fromLatin1("update-mime-database"));
- if (umd.isEmpty())
+ const QString umdCommand = QString::fromLatin1("update-mime-database");
+ const QString umd = QStandardPaths::findExecutable(umdCommand);
+ if (umd.isEmpty()) {
+ qWarning("%s does not exist.", qPrintable(umdCommand));
return false;
+ }
QProcess proc;
proc.setProcessChannelMode(QProcess::MergedChannels); // silence output
- proc.start(umd, QStringList() << path);
+ proc.start(umd, QStringList(path));
+ if (!proc.waitForStarted()) {
+ qWarning("Cannot start %s: %s",
+ qPrintable(umd), qPrintable(proc.errorString()));
+ return false;
+ }
proc.waitForFinished();
//qDebug() << "runUpdateMimeDatabase" << path;
return true;
@@ -733,7 +789,7 @@ static bool waitAndRunUpdateMimeDatabase(const QString &path)
{
QFileInfo mimeCacheInfo(path + QString::fromLatin1("/mime.cache"));
if (mimeCacheInfo.exists()) {
- // Wait until the begining of the next second
+ // Wait until the beginning of the next second
while (mimeCacheInfo.lastModified().secsTo(QDateTime::currentDateTime()) == 0) {
QTest::qSleep(200);
}
@@ -767,16 +823,15 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
QMimeDatabase db;
QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
- const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml");
- const QString srcFile = QFile::decodeName(SRCDIR) + fileName;
-
- QDir here = QDir::currentPath();
- const QString mimeDir = here.absolutePath() + QLatin1String("/mime");
+ const QString mimeDir = m_globalXdgDir + QLatin1String("/mime");
const QString destDir = mimeDir + QLatin1String("/packages/");
- const QString destFile = destDir + fileName;
+ const QString destFile = destDir + QLatin1String(yastFileName);
QFile::remove(destFile);
//qDebug() << destFile;
- QVERIFY(QFile::copy(srcFile, destFile));
+
+ if (!QFileInfo(destDir).isDir())
+ QVERIFY(QDir(m_globalXdgDir).mkpath(destDir));
+ QVERIFY(QFile::copy(m_yastMimeTypes, destFile));
if (!waitAndRunUpdateMimeDatabase(mimeDir))
QSKIP("shared-mime-info not found, skipping mime.cache test");
@@ -801,16 +856,17 @@ void tst_QMimeDatabase::installNewLocalMimeType()
QMimeDatabase db;
QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
- const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml");
- const QString srcFile = QFile::decodeName(SRCDIR) + fileName;
- const QString mimeDir = m_dataHome + QLatin1String("/mime");
+ const QString mimeDir = m_localXdgDir + QLatin1String("/mime");
const QString destDir = mimeDir + QLatin1String("/packages/");
QDir().mkpath(destDir);
- const QString destFile = destDir + fileName;
+ const QString destFile = destDir + QLatin1String(yastFileName);
QFile::remove(destFile);
- QVERIFY(QFile::copy(srcFile, destFile));
- if (!runUpdateMimeDatabase(mimeDir))
- QSKIP("shared-mime-info not found, skipping mime.cache test");;
+ QVERIFY(QFile::copy(m_yastMimeTypes, destFile));
+ if (!runUpdateMimeDatabase(mimeDir)) {
+ const QString skipWarning = QStringLiteral("shared-mime-info not found, skipping mime.cache test (")
+ + QDir::toNativeSeparators(mimeDir) + QLatin1Char(')');
+ QSKIP(qPrintable(skipWarning));
+ }
QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
QString::fromLatin1("text/x-suse-ymu"));
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
index 869990401c..94baf77ee9 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
@@ -43,6 +43,7 @@
#define TST_QMIMEDATABASE_H
#include <QtCore/QObject>
+#include <QtCore/QTemporaryDir>
class tst_QMimeDatabase : public QObject
{
@@ -53,7 +54,6 @@ public:
private slots:
void initTestCase();
- void cleanupTestCase();
void mimeTypeForName();
void mimeTypeForFileName_data();
@@ -93,7 +93,13 @@ private slots:
void installNewLocalMimeType();
private:
- QString m_dataHome;
+ void init(); // test-specific
+
+ QString m_globalXdgDir;
+ QString m_localXdgDir;
+ QString m_yastMimeTypes;
+ QTemporaryDir m_temporaryDir;
+ QString m_testSuite;
};
#endif // TST_QMIMEDATABASE_H
diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
index 1732f628ea..e72af11fbb 100644
--- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp
+++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
@@ -580,7 +580,9 @@ void tst_QChar::normalization_data()
int linenum = 0;
int part = 0;
- QFile f(QFINDTESTDATA("NormalizationTest.txt"));
+ QString testFile = QFINDTESTDATA("NormalizationTest.txt");
+ QVERIFY2(!testFile.isEmpty(), "NormalizationTest.txt not found!");
+ QFile f(testFile);
QVERIFY(f.exists());
f.open(QIODevice::ReadOnly);
diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro
index a97350ca3f..b61f51d53a 100644
--- a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro
+++ b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro
@@ -6,6 +6,3 @@ CONFIG -= app_bundle
QT = core
-# This app is testdata for tst_qlocale
-target.path = $$[QT_INSTALL_TESTS]/tst_qlocale/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/tools/qlocale/test/test.pro
index eafd8c1699..24dcc0638a 100644
--- a/tests/auto/corelib/tools/qlocale/test/test.pro
+++ b/tests/auto/corelib/tools/qlocale/test/test.pro
@@ -12,6 +12,8 @@ win32 {
TARGET = ../../release/tst_qlocale
}
}
-TESTDATA += syslocaleapp
+
+load(testcase) # for target.path and installTestHelperApp()
+installTestHelperApp("../syslocaleapp/syslocaleapp",syslocaleapp,syslocaleapp)
mac: CONFIG += insignificant_test # QTBUG-22769
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 02acb00548..b3b573c64b 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -809,11 +809,7 @@ void tst_QLocale::negativeZero()
{
double negativeZero( 0.0 ); // Initialise to zero.
uchar *ptr = (uchar *)&negativeZero;
-#ifdef QT_ARMFPA
- ptr[3] = 0x80;
-#else
ptr[QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 7] = 0x80;
-#endif
QString s = QString::number(negativeZero);
QCOMPARE(s, QString("0"));
}
diff --git a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp b/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp
index a697e23270..5470de76ee 100644
--- a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp
+++ b/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp
@@ -81,6 +81,7 @@ private slots:
void interval();
void validityCheck_data();
void validityCheck();
+ void escapeSequences();
};
// Testing get/set functions
@@ -118,43 +119,43 @@ void tst_QRegExp::indexIn_data()
stri.setNum(i);
// anchors
- QTest::newRow( stri + "anc00" ) << QString("a(?=)z") << QString("az") << 0 << 2 << QStringList();
- QTest::newRow( stri + "anc01" ) << QString("a(?!)z") << QString("az") << -1 << -1 << QStringList();
- QTest::newRow( stri + "anc02" ) << QString("a(?:(?=)|(?=))z") << QString("az") << 0 << 2
+ QTest::newRow(qPrintable(stri + "anc00")) << QString("a(?=)z") << QString("az") << 0 << 2 << QStringList();
+ QTest::newRow(qPrintable(stri + "anc01")) << QString("a(?!)z") << QString("az") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "anc02")) << QString("a(?:(?=)|(?=))z") << QString("az") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "anc03" ) << QString("a(?:(?=)|(?!))z") << QString("az") << 0 << 2
+ QTest::newRow(qPrintable(stri + "anc03")) << QString("a(?:(?=)|(?!))z") << QString("az") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "anc04" ) << QString("a(?:(?!)|(?=))z") << QString("az") << 0 << 2
+ QTest::newRow(qPrintable(stri + "anc04")) << QString("a(?:(?!)|(?=))z") << QString("az") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "anc05" ) << QString("a(?:(?!)|(?!))z") << QString("az") << -1 << -1
+ QTest::newRow(qPrintable(stri + "anc05")) << QString("a(?:(?!)|(?!))z") << QString("az") << -1 << -1
<< QStringList();
- QTest::newRow( stri + "anc06" ) << QString("a(?:(?=)|b)z") << QString("az") << 0 << 2
+ QTest::newRow(qPrintable(stri + "anc06")) << QString("a(?:(?=)|b)z") << QString("az") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "anc07" ) << QString("a(?:(?=)|b)z") << QString("abz") << 0 << 3
+ QTest::newRow(qPrintable(stri + "anc07")) << QString("a(?:(?=)|b)z") << QString("abz") << 0 << 3
<< QStringList();
- QTest::newRow( stri + "anc08" ) << QString("a(?:(?!)|b)z") << QString("az") << -1 << -1
+ QTest::newRow(qPrintable(stri + "anc08")) << QString("a(?:(?!)|b)z") << QString("az") << -1 << -1
<< QStringList();
- QTest::newRow( stri + "anc09" ) << QString("a(?:(?!)|b)z") << QString("abz") << 0 << 3
+ QTest::newRow(qPrintable(stri + "anc09")) << QString("a(?:(?!)|b)z") << QString("abz") << 0 << 3
<< QStringList();
#if 0
- QTest::newRow( stri + "anc10" ) << QString("a?(?=^b$)") << QString("ab") << 0 << 1
+ QTest::newRow(qPrintable(stri + "anc10")) << QString("a?(?=^b$)") << QString("ab") << 0 << 1
<< QStringList();
- QTest::newRow( stri + "anc11" ) << QString("a?(?=^b$)") << QString("b") << 0 << 0
+ QTest::newRow(qPrintable(stri + "anc11")) << QString("a?(?=^b$)") << QString("b") << 0 << 0
<< QStringList();
#endif
// back-references
- QTest::newRow( stri + "bref00" ) << QString("(a*)(\\1)") << QString("aaaaa") << 0 << 4
+ QTest::newRow(qPrintable(stri + "bref00")) << QString("(a*)(\\1)") << QString("aaaaa") << 0 << 4
<< QStringList( QStringList() << "aa" << "aa" );
- QTest::newRow( stri + "bref01" ) << QString("<(\\w*)>.+</\\1>") << QString("<b>blabla</b>bla</>")
+ QTest::newRow(qPrintable(stri + "bref01")) << QString("<(\\w*)>.+</\\1>") << QString("<b>blabla</b>bla</>")
<< 0 << 13 << QStringList( QStringList() << "b" );
- QTest::newRow( stri + "bref02" ) << QString("<(\\w*)>.+</\\1>") << QString("<>blabla</b>bla</>")
+ QTest::newRow(qPrintable(stri + "bref02")) << QString("<(\\w*)>.+</\\1>") << QString("<>blabla</b>bla</>")
<< 0 << 18 << QStringList( QStringList() << "" );
- QTest::newRow( stri + "bref03" ) << QString("((a*\\2)\\2)") << QString("aaaa") << 0 << 4
+ QTest::newRow(qPrintable(stri + "bref03")) << QString("((a*\\2)\\2)") << QString("aaaa") << 0 << 4
<< QStringList( QStringList() << QString("aaaa") << "aa" );
- QTest::newRow( stri + "bref04" ) << QString("^(aa+)\\1+$") << QString("aaaaaa") << 0 << 6
+ QTest::newRow(qPrintable(stri + "bref04")) << QString("^(aa+)\\1+$") << QString("aaaaaa") << 0 << 6
<< QStringList( QStringList() << QString("aa") );
- QTest::newRow( stri + "bref05" ) << QString("^(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)"
+ QTest::newRow(qPrintable(stri + "bref05")) << QString("^(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)"
"\\14\\13\\12\\11\\10\\9\\8\\7\\6\\5\\4\\3\\2\\1")
<< QString("12345678910111213141413121110987654321") << 0 << 38
<< QStringList( QStringList() << "1" << "2" << "3" << "4" << "5" << "6"
@@ -162,49 +163,49 @@ void tst_QRegExp::indexIn_data()
<< "12" << "13" << "14");
// captures
- QTest::newRow( stri + "cap00" ) << QString("(a*)") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "cap00")) << QString("(a*)") << QString("") << 0 << 0
<< QStringList( QStringList() << QString("") );
- QTest::newRow( stri + "cap01" ) << QString("(a*)") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cap01")) << QString("(a*)") << QString("aaa") << 0 << 3
<< QStringList( QStringList() << "aaa" );
- QTest::newRow( stri + "cap02" ) << QString("(a*)") << QString("baaa") << 0 << 0
+ QTest::newRow(qPrintable(stri + "cap02")) << QString("(a*)") << QString("baaa") << 0 << 0
<< QStringList( QStringList() << QString("") );
- QTest::newRow( stri + "cap03" ) << QString("(a*)(a*)") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cap03")) << QString("(a*)(a*)") << QString("aaa") << 0 << 3
<< QStringList( QStringList() << QString("aaa") << QString("") );
- QTest::newRow( stri + "cap04" ) << QString("(a*)(b*)") << QString("aaabbb") << 0 << 6
+ QTest::newRow(qPrintable(stri + "cap04")) << QString("(a*)(b*)") << QString("aaabbb") << 0 << 6
<< QStringList( QStringList() << QString("aaa") << QString("bbb") );
- QTest::newRow( stri + "cap06" ) << QString("(a*)a*") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cap06")) << QString("(a*)a*") << QString("aaa") << 0 << 3
<< QStringList( QStringList() << QString("aaa") );
- QTest::newRow( stri + "cap07" ) << QString("((a*a*)*)") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cap07")) << QString("((a*a*)*)") << QString("aaa") << 0 << 3
<< QStringList( QStringList() << "aaa" << QString("aaa") );
- QTest::newRow( stri + "cap08" ) << QString("(((a)*(b)*)*)") << QString("ababa") << 0 << 5
+ QTest::newRow(qPrintable(stri + "cap08")) << QString("(((a)*(b)*)*)") << QString("ababa") << 0 << 5
<< QStringList( QStringList() << QString("ababa") << QString("a") << QString("a")
<< "" );
- QTest::newRow( stri + "cap09" ) << QString("(((a)*(b)*)c)*") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "cap09")) << QString("(((a)*(b)*)c)*") << QString("") << 0 << 0
<< QStringList( QStringList() << QString("") << QString("") << QString("") << QString("") );
- QTest::newRow( stri + "cap10" ) << QString("(((a)*(b)*)c)*") << QString("abc") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cap10")) << QString("(((a)*(b)*)c)*") << QString("abc") << 0 << 3
<< QStringList( QStringList() << "abc" << "ab" << "a"
<< "b" );
- QTest::newRow( stri + "cap11" ) << QString("(((a)*(b)*)c)*") << QString("abcc") << 0 << 4
+ QTest::newRow(qPrintable(stri + "cap11")) << QString("(((a)*(b)*)c)*") << QString("abcc") << 0 << 4
<< QStringList( QStringList() << "c" << "" << "" << "" );
- QTest::newRow( stri + "cap12" ) << QString("(((a)*(b)*)c)*") << QString("abcac") << 0 << 5
+ QTest::newRow(qPrintable(stri + "cap12")) << QString("(((a)*(b)*)c)*") << QString("abcac") << 0 << 5
<< QStringList( QStringList() << "ac" << "a" << "a" << "" );
- QTest::newRow( stri + "cap13" ) << QString("(to|top)?(o|polo)?(gical|o?logical)")
+ QTest::newRow(qPrintable(stri + "cap13")) << QString("(to|top)?(o|polo)?(gical|o?logical)")
<< QString("topological") << 0 << 11
<< QStringList( QStringList() << "top" << "o"
<< "logical" );
- QTest::newRow( stri + "cap14" ) << QString("(a)+") << QString("aaaa") << 0 << 4
+ QTest::newRow(qPrintable(stri + "cap14")) << QString("(a)+") << QString("aaaa") << 0 << 4
<< QStringList( QStringList() << "a" );
// concatenation
- QTest::newRow( stri + "cat00" ) << QString("") << QString("") << 0 << 0 << QStringList();
- QTest::newRow( stri + "cat01" ) << QString("") << QString("a") << 0 << 0 << QStringList();
- QTest::newRow( stri + "cat02" ) << QString("a") << QString("") << -1 << -1 << QStringList();
- QTest::newRow( stri + "cat03" ) << QString("a") << QString("a") << 0 << 1 << QStringList();
- QTest::newRow( stri + "cat04" ) << QString("a") << QString("b") << -1 << -1 << QStringList();
- QTest::newRow( stri + "cat05" ) << QString("b") << QString("a") << -1 << -1 << QStringList();
- QTest::newRow( stri + "cat06" ) << QString("ab") << QString("ab") << 0 << 2 << QStringList();
- QTest::newRow( stri + "cat07" ) << QString("ab") << QString("ba") << -1 << -1 << QStringList();
- QTest::newRow( stri + "cat08" ) << QString("abab") << QString("abbaababab") << 4 << 4 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat00")) << QString("") << QString("") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat01")) << QString("") << QString("a") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat02")) << QString("a") << QString("") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat03")) << QString("a") << QString("a") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat04")) << QString("a") << QString("b") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat05")) << QString("b") << QString("a") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat06")) << QString("ab") << QString("ab") << 0 << 2 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat07")) << QString("ab") << QString("ba") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "cat08")) << QString("abab") << QString("abbaababab") << 4 << 4 << QStringList();
indexIn_addMoreRows(stri);
}
@@ -213,96 +214,96 @@ void tst_QRegExp::indexIn_data()
void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
{
// from Perl Cookbook
- QTest::newRow( stri + "cook00" ) << QString("^(m*)(d?c{0,3}|c[dm])(1?x{0,3}|x[lc])(v?i{0,3}|i[vx])$")
+ QTest::newRow(qPrintable(stri + "cook00")) << QString("^(m*)(d?c{0,3}|c[dm])(1?x{0,3}|x[lc])(v?i{0,3}|i[vx])$")
<< QString("mmxl") << 0 << 4
<< QStringList( QStringList() << "mm" << "" << "xl"
<< "" );
- QTest::newRow( stri + "cook01" ) << QString("(\\S+)(\\s+)(\\S+)") << QString(" a b") << 1 << 5
+ QTest::newRow(qPrintable(stri + "cook01")) << QString("(\\S+)(\\s+)(\\S+)") << QString(" a b") << 1 << 5
<< QStringList( QStringList() << "a" << " " << "b" );
- QTest::newRow( stri + "cook02" ) << QString("(\\w+)\\s*=\\s*(.*)\\s*$") << QString(" PATH=. ") << 1
+ QTest::newRow(qPrintable(stri + "cook02")) << QString("(\\w+)\\s*=\\s*(.*)\\s*$") << QString(" PATH=. ") << 1
<< 7 << QStringList( QStringList() << "PATH" << ". " );
- QTest::newRow( stri + "cook03" ) << QString(".{80,}")
+ QTest::newRow(qPrintable(stri + "cook03")) << QString(".{80,}")
<< QString("0000000011111111222222223333333344444444555"
"5555566666666777777778888888899999999000000"
"00aaaaaaaa")
<< 0 << 96 << QStringList();
- QTest::newRow( stri + "cook04" ) << QString("(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+)")
+ QTest::newRow(qPrintable(stri + "cook04")) << QString("(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+)")
<< QString("1978/05/24 07:30:00") << 0 << 19
<< QStringList( QStringList() << "1978" << "05" << "24"
<< "07" << "30" << "00" );
- QTest::newRow( stri + "cook05" ) << QString("/usr/bin") << QString("/usr/local/bin:/usr/bin")
+ QTest::newRow(qPrintable(stri + "cook05")) << QString("/usr/bin") << QString("/usr/local/bin:/usr/bin")
<< 15 << 8 << QStringList();
- QTest::newRow( stri + "cook06" ) << QString("%([0-9A-Fa-f]{2})") << QString("http://%7f") << 7 << 3
+ QTest::newRow(qPrintable(stri + "cook06")) << QString("%([0-9A-Fa-f]{2})") << QString("http://%7f") << 7 << 3
<< QStringList( QStringList() << "7f" );
- QTest::newRow( stri + "cook07" ) << QString("/\\*.*\\*/") << QString("i++; /* increment i */") << 5
+ QTest::newRow(qPrintable(stri + "cook07")) << QString("/\\*.*\\*/") << QString("i++; /* increment i */") << 5
<< 17 << QStringList();
- QTest::newRow( stri + "cook08" ) << QString("^\\s+") << QString(" aaa ") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cook08")) << QString("^\\s+") << QString(" aaa ") << 0 << 3
<< QStringList();
- QTest::newRow( stri + "cook09" ) << QString("\\s+$") << QString(" aaa ") << 6 << 3
+ QTest::newRow(qPrintable(stri + "cook09")) << QString("\\s+$") << QString(" aaa ") << 6 << 3
<< QStringList();
- QTest::newRow( stri + "cook10" ) << QString("^.*::") << QString("Box::cat") << 0 << 5
+ QTest::newRow(qPrintable(stri + "cook10")) << QString("^.*::") << QString("Box::cat") << 0 << 5
<< QStringList();
- QTest::newRow( stri + "cook11" ) << QString("^([01]?\\d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\"
+ QTest::newRow(qPrintable(stri + "cook11")) << QString("^([01]?\\d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\"
"d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-"
"4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-4]\\d|25["
"0-5])$")
<< QString("255.00.40.30") << 0 << 12
<< QStringList( QStringList() << "255" << "00" << "40"
<< "30" );
- QTest::newRow( stri + "cook12" ) << QString("^.*/") << QString(" /usr/local/bin/moc") << 0 << 16
+ QTest::newRow(qPrintable(stri + "cook12")) << QString("^.*/") << QString(" /usr/local/bin/moc") << 0 << 16
<< QStringList();
- QTest::newRow( stri + "cook13" ) << QString(":co#(\\d+):") << QString("bla:co#55:") << 3 << 7
+ QTest::newRow(qPrintable(stri + "cook13")) << QString(":co#(\\d+):") << QString("bla:co#55:") << 3 << 7
<< QStringList( QStringList() << "55" );
- QTest::newRow( stri + "cook14" ) << QString("linux") << QString("alphalinuxinunix") << 5 << 5
+ QTest::newRow(qPrintable(stri + "cook14")) << QString("linux") << QString("alphalinuxinunix") << 5 << 5
<< QStringList();
- QTest::newRow( stri + "cook15" ) << QString("(\\d+\\.?\\d*|\\.\\d+)") << QString("0.0.5") << 0 << 3
+ QTest::newRow(qPrintable(stri + "cook15")) << QString("(\\d+\\.?\\d*|\\.\\d+)") << QString("0.0.5") << 0 << 3
<< QStringList( QStringList() << "0.0" );
// mathematical trivia
- QTest::newRow( stri + "math00" ) << QString("^(a\\1*)$") << QString("a") << 0 << 1
+ QTest::newRow(qPrintable(stri + "math00")) << QString("^(a\\1*)$") << QString("a") << 0 << 1
<< QStringList( QStringList() << "a" );
- QTest::newRow( stri + "math01" ) << QString("^(a\\1*)$") << QString("aa") << 0 << 2
+ QTest::newRow(qPrintable(stri + "math01")) << QString("^(a\\1*)$") << QString("aa") << 0 << 2
<< QStringList( QStringList() << "aa" );
- QTest::newRow( stri + "math02" ) << QString("^(a\\1*)$") << QString("aaa") << -1 << -1
+ QTest::newRow(qPrintable(stri + "math02")) << QString("^(a\\1*)$") << QString("aaa") << -1 << -1
<< QStringList( QStringList() << QString() );
- QTest::newRow( stri + "math03" ) << QString("^(a\\1*)$") << QString("aaaa") << 0 << 4
+ QTest::newRow(qPrintable(stri + "math03")) << QString("^(a\\1*)$") << QString("aaaa") << 0 << 4
<< QStringList( QStringList() << "aaaa" );
- QTest::newRow( stri + "math04" ) << QString("^(a\\1*)$") << QString("aaaaa") << -1 << -1
+ QTest::newRow(qPrintable(stri + "math04")) << QString("^(a\\1*)$") << QString("aaaaa") << -1 << -1
<< QStringList( QStringList() << QString() );
- QTest::newRow( stri + "math05" ) << QString("^(a\\1*)$") << QString("aaaaaa") << -1 << -1
+ QTest::newRow(qPrintable(stri + "math05")) << QString("^(a\\1*)$") << QString("aaaaaa") << -1 << -1
<< QStringList( QStringList() << QString() );
- QTest::newRow( stri + "math06" ) << QString("^(a\\1*)$") << QString("aaaaaaa") << -1 << -1
+ QTest::newRow(qPrintable(stri + "math06")) << QString("^(a\\1*)$") << QString("aaaaaaa") << -1 << -1
<< QStringList( QStringList() << QString() );
- QTest::newRow( stri + "math07" ) << QString("^(a\\1*)$") << QString("aaaaaaaa") << 0 << 8
+ QTest::newRow(qPrintable(stri + "math07")) << QString("^(a\\1*)$") << QString("aaaaaaaa") << 0 << 8
<< QStringList( QStringList() << "aaaaaaaa" );
- QTest::newRow( stri + "math08" ) << QString("^(a\\1*)$") << QString("aaaaaaaaa") << -1 << -1
+ QTest::newRow(qPrintable(stri + "math08")) << QString("^(a\\1*)$") << QString("aaaaaaaaa") << -1 << -1
<< QStringList( QStringList() << QString() );
- QTest::newRow( stri + "math09" ) << QString("^a(?:a(\\1a))*$") << QString("a") << 0 << 1
+ QTest::newRow(qPrintable(stri + "math09")) << QString("^a(?:a(\\1a))*$") << QString("a") << 0 << 1
<< QStringList( QStringList() << "" );
- QTest::newRow( stri + "math10" ) << QString("^a(?:a(\\1a))*$") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "math10")) << QString("^a(?:a(\\1a))*$") << QString("aaa") << 0 << 3
<< QStringList( QStringList() << "a" );
- QTest::newRow( stri + "math13" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
+ QTest::newRow(qPrintable(stri + "math13")) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
"?=a$)))*a$")
<< QString("aaa") << 0 << 3
<< QStringList( QStringList() << "a" << "a" << "" );
- QTest::newRow( stri + "math14" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
+ QTest::newRow(qPrintable(stri + "math14")) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
"?=a$)))*a$")
<< QString("aaaaa") << 0 << 5
<< QStringList( QStringList() << "a" << "a" << "aa" );
- QTest::newRow( stri + "math17" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
+ QTest::newRow(qPrintable(stri + "math17")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
<< QString("aaa") << 0 << 3
<< QStringList( QStringList() << "" << "" << "" << "aaa" << "a" << "aa" );
- QTest::newRow( stri + "math18" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
+ QTest::newRow(qPrintable(stri + "math18")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
<< QString("aaaaa") << 0 << 5
<< QStringList( QStringList() << "aaaaa" << "a" << "aaa" << "" << "" << "" );
- QTest::newRow( stri + "math19" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
+ QTest::newRow(qPrintable(stri + "math19")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
<< QString("aaaaaaaa") << 0 << 8
<< QStringList( QStringList() << "" << "" << "" << "aaaaaaaa" << "a" << "aa" );
- QTest::newRow( stri + "math20" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
+ QTest::newRow(qPrintable(stri + "math20")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
<< QString("aaaaaaaaa") << -1 << -1
<< QStringList( QStringList() << QString()
@@ -311,7 +312,7 @@ void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
<< QString()
<< QString()
<< QString() );
- QTest::newRow( stri + "math21" ) << QString("^(aa+)\\1+$") << QString("aaaaaaaaaaaa") << 0 << 12
+ QTest::newRow(qPrintable(stri + "math21")) << QString("^(aa+)\\1+$") << QString("aaaaaaaaaaaa") << 0 << 12
<< QStringList( QStringList() << "aa" );
static const char * const squareRegExp[] = {
@@ -349,129 +350,129 @@ void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
}
// miscellaneous
- QTest::newRow( stri + "misc00" ) << QString(email)
+ QTest::newRow(qPrintable(stri + "misc00")) << QString(email)
<< QString("email123@example.com") << 0 << 20
<< QStringList();
- QTest::newRow( stri + "misc01" ) << QString("[0-9]*\\.[0-9]+") << QString("pi = 3.14") << 5 << 4
+ QTest::newRow(qPrintable(stri + "misc01")) << QString("[0-9]*\\.[0-9]+") << QString("pi = 3.14") << 5 << 4
<< QStringList();
// or operator
- QTest::newRow( stri + "or00" ) << QString("(?:|b)") << QString("xxx") << 0 << 0 << QStringList();
- QTest::newRow( stri + "or01" ) << QString("(?:|b)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow( stri + "or02" ) << QString("(?:b|)") << QString("") << 0 << 0 << QStringList();
- QTest::newRow( stri + "or03" ) << QString("(?:b|)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow( stri + "or04" ) << QString("(?:||b||)") << QString("") << 0 << 0 << QStringList();
- QTest::newRow( stri + "or05" ) << QString("(?:||b||)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow( stri + "or06" ) << QString("(?:a|b)") << QString("") << -1 << -1 << QStringList();
- QTest::newRow( stri + "or07" ) << QString("(?:a|b)") << QString("cc") << -1 << -1 << QStringList();
- QTest::newRow( stri + "or08" ) << QString("(?:a|b)") << QString("abc") << 0 << 1 << QStringList();
- QTest::newRow( stri + "or09" ) << QString("(?:a|b)") << QString("cba") << 1 << 1 << QStringList();
- QTest::newRow( stri + "or10" ) << QString("(?:ab|ba)") << QString("aba") << 0 << 2
+ QTest::newRow(qPrintable(stri + "or00")) << QString("(?:|b)") << QString("xxx") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "or01")) << QString("(?:|b)") << QString("b") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or02")) << QString("(?:b|)") << QString("") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "or03")) << QString("(?:b|)") << QString("b") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or04")) << QString("(?:||b||)") << QString("") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "or05")) << QString("(?:||b||)") << QString("b") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or06")) << QString("(?:a|b)") << QString("") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or07")) << QString("(?:a|b)") << QString("cc") << -1 << -1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or08")) << QString("(?:a|b)") << QString("abc") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or09")) << QString("(?:a|b)") << QString("cba") << 1 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "or10")) << QString("(?:ab|ba)") << QString("aba") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "or11" ) << QString("(?:ab|ba)") << QString("bab") << 0 << 2
+ QTest::newRow(qPrintable(stri + "or11")) << QString("(?:ab|ba)") << QString("bab") << 0 << 2
<< QStringList();
- QTest::newRow( stri + "or12" ) << QString("(?:ab|ba)") << QString("caba") << 1 << 2
+ QTest::newRow(qPrintable(stri + "or12")) << QString("(?:ab|ba)") << QString("caba") << 1 << 2
<< QStringList();
- QTest::newRow( stri + "or13" ) << QString("(?:ab|ba)") << QString("cbab") << 1 << 2
+ QTest::newRow(qPrintable(stri + "or13")) << QString("(?:ab|ba)") << QString("cbab") << 1 << 2
<< QStringList();
// quantifiers
- QTest::newRow( stri + "qua00" ) << QString("((([a-j])){0,0})") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua00")) << QString("((([a-j])){0,0})") << QString("") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua01" ) << QString("((([a-j])){0,0})") << QString("a") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua01")) << QString("((([a-j])){0,0})") << QString("a") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua02" ) << QString("((([a-j])){0,0})") << QString("xyz") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua02")) << QString("((([a-j])){0,0})") << QString("xyz") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua03" ) << QString("((([a-j]))?)") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua03")) << QString("((([a-j]))?)") << QString("") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua04" ) << QString("((([a-j]))?)") << QString("a") << 0 << 1
+ QTest::newRow(qPrintable(stri + "qua04")) << QString("((([a-j]))?)") << QString("a") << 0 << 1
<< QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow( stri + "qua05" ) << QString("((([a-j]))?)") << QString("x") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua05")) << QString("((([a-j]))?)") << QString("x") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua06" ) << QString("((([a-j]))?)") << QString("ab") << 0 << 1
+ QTest::newRow(qPrintable(stri + "qua06")) << QString("((([a-j]))?)") << QString("ab") << 0 << 1
<< QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow( stri + "qua07" ) << QString("((([a-j]))?)") << QString("xa") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua07")) << QString("((([a-j]))?)") << QString("xa") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua08" ) << QString("((([a-j])){0,3})") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua08")) << QString("((([a-j])){0,3})") << QString("") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua09" ) << QString("((([a-j])){0,3})") << QString("a") << 0 << 1
+ QTest::newRow(qPrintable(stri + "qua09")) << QString("((([a-j])){0,3})") << QString("a") << 0 << 1
<< QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow( stri + "qua10" ) << QString("((([a-j])){0,3})") << QString("abcd") << 0 << 3
+ QTest::newRow(qPrintable(stri + "qua10")) << QString("((([a-j])){0,3})") << QString("abcd") << 0 << 3
<< QStringList( QStringList() << "abc" << "c" << "c" );
- QTest::newRow( stri + "qua11" ) << QString("((([a-j])){0,3})") << QString("abcde") << 0 << 3
+ QTest::newRow(qPrintable(stri + "qua11")) << QString("((([a-j])){0,3})") << QString("abcde") << 0 << 3
<< QStringList( QStringList() << "abc" << "c" << "c" );
- QTest::newRow( stri + "qua12" ) << QString("((([a-j])){2,4})") << QString("a") << -1 << -1
+ QTest::newRow(qPrintable(stri + "qua12")) << QString("((([a-j])){2,4})") << QString("a") << -1 << -1
<< QStringList( QStringList() << QString()
<< QString()
<< QString() );
- QTest::newRow( stri + "qua13" ) << QString("((([a-j])){2,4})") << QString("ab") << 0 << 2
+ QTest::newRow(qPrintable(stri + "qua13")) << QString("((([a-j])){2,4})") << QString("ab") << 0 << 2
<< QStringList( QStringList() << "ab" << "b" << "b" );
- QTest::newRow( stri + "qua14" ) << QString("((([a-j])){2,4})") << QString("abcd") << 0 << 4
+ QTest::newRow(qPrintable(stri + "qua14")) << QString("((([a-j])){2,4})") << QString("abcd") << 0 << 4
<< QStringList( QStringList() << "abcd" << "d" << "d" );
- QTest::newRow( stri + "qua15" ) << QString("((([a-j])){2,4})") << QString("abcdef") << 0 << 4
+ QTest::newRow(qPrintable(stri + "qua15")) << QString("((([a-j])){2,4})") << QString("abcdef") << 0 << 4
<< QStringList( QStringList() << "abcd" << "d" << "d" );
- QTest::newRow( stri + "qua16" ) << QString("((([a-j])){2,4})") << QString("xaybcd") << 3 << 3
+ QTest::newRow(qPrintable(stri + "qua16")) << QString("((([a-j])){2,4})") << QString("xaybcd") << 3 << 3
<< QStringList( QStringList() << "bcd" << "d" << "d" );
- QTest::newRow( stri + "qua17" ) << QString("((([a-j])){0,})") << QString("abcdefgh") << 0 << 8
+ QTest::newRow(qPrintable(stri + "qua17")) << QString("((([a-j])){0,})") << QString("abcdefgh") << 0 << 8
<< QStringList( QStringList() << "abcdefgh" << "h" << "h" );
- QTest::newRow( stri + "qua18" ) << QString("((([a-j])){,0})") << QString("abcdefgh") << 0 << 0
+ QTest::newRow(qPrintable(stri + "qua18")) << QString("((([a-j])){,0})") << QString("abcdefgh") << 0 << 0
<< QStringList( QStringList() << "" << "" << "" );
- QTest::newRow( stri + "qua19" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("123332333") << 0
+ QTest::newRow(qPrintable(stri + "qua19")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("123332333") << 0
<< 9
<< QStringList( QStringList() << "123332333" << "2333"
<< "3" );
- QTest::newRow( stri + "qua20" ) << QString("(1(2(3){3,4}){2,3}){1,2}")
+ QTest::newRow(qPrintable(stri + "qua20")) << QString("(1(2(3){3,4}){2,3}){1,2}")
<< QString("12333323333233331233332333323333") << 0 << 32
<< QStringList( QStringList() << "1233332333323333"
<< "23333" << "3" );
- QTest::newRow( stri + "qua21" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("") << -1 << -1
+ QTest::newRow(qPrintable(stri + "qua21")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("") << -1 << -1
<< QStringList( QStringList() << QString()
<< QString()
<< QString() );
- QTest::newRow( stri + "qua22" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333") << -1
+ QTest::newRow(qPrintable(stri + "qua22")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333") << -1
<< -1
<< QStringList( QStringList() << QString()
<< QString()
<< QString() );
- QTest::newRow( stri + "qua23" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333233") << -1
+ QTest::newRow(qPrintable(stri + "qua23")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333233") << -1
<< -1
<< QStringList( QStringList() << QString()
<< QString()
<< QString() );
- QTest::newRow( stri + "qua24" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("122333") << -1
+ QTest::newRow(qPrintable(stri + "qua24")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("122333") << -1
<< -1
<< QStringList( QStringList() << QString()
<< QString()
<< QString() );
// star operator
- QTest::newRow( stri + "star00" ) << QString("(?:)*") << QString("") << 0 << 0 << QStringList();
- QTest::newRow( stri + "star01" ) << QString("(?:)*") << QString("abc") << 0 << 0 << QStringList();
- QTest::newRow( stri + "star02" ) << QString("(?:a)*") << QString("") << 0 << 0 << QStringList();
- QTest::newRow( stri + "star03" ) << QString("(?:a)*") << QString("a") << 0 << 1 << QStringList();
- QTest::newRow( stri + "star04" ) << QString("(?:a)*") << QString("aaa") << 0 << 3 << QStringList();
- QTest::newRow( stri + "star05" ) << QString("(?:a)*") << QString("bbbbaaa") << 0 << 0
+ QTest::newRow(qPrintable(stri + "star00")) << QString("(?:)*") << QString("") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "star01")) << QString("(?:)*") << QString("abc") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "star02")) << QString("(?:a)*") << QString("") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "star03")) << QString("(?:a)*") << QString("a") << 0 << 1 << QStringList();
+ QTest::newRow(qPrintable(stri + "star04")) << QString("(?:a)*") << QString("aaa") << 0 << 3 << QStringList();
+ QTest::newRow(qPrintable(stri + "star05")) << QString("(?:a)*") << QString("bbbbaaa") << 0 << 0
<< QStringList();
- QTest::newRow( stri + "star06" ) << QString("(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 0
+ QTest::newRow(qPrintable(stri + "star06")) << QString("(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 0
<< QStringList();
- QTest::newRow( stri + "star07" ) << QString("(?:b)*(?:a)*") << QString("") << 0 << 0
+ QTest::newRow(qPrintable(stri + "star07")) << QString("(?:b)*(?:a)*") << QString("") << 0 << 0
<< QStringList();
- QTest::newRow( stri + "star08" ) << QString("(?:b)*(?:a)*") << QString("a") << 0 << 1
+ QTest::newRow(qPrintable(stri + "star08")) << QString("(?:b)*(?:a)*") << QString("a") << 0 << 1
<< QStringList();
- QTest::newRow( stri + "star09" ) << QString("(?:b)*(?:a)*") << QString("aaa") << 0 << 3
+ QTest::newRow(qPrintable(stri + "star09")) << QString("(?:b)*(?:a)*") << QString("aaa") << 0 << 3
<< QStringList();
- QTest::newRow( stri + "star10" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaa") << 0 << 7
+ QTest::newRow(qPrintable(stri + "star10")) << QString("(?:b)*(?:a)*") << QString("bbbbaaa") << 0 << 7
<< QStringList();
- QTest::newRow( stri + "star11" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 7
+ QTest::newRow(qPrintable(stri + "star11")) << QString("(?:b)*(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 7
<< QStringList();
- QTest::newRow( stri + "star12" ) << QString("(?:a|b)*") << QString("c") << 0 << 0 << QStringList();
- QTest::newRow( stri + "star13" ) << QString("(?:a|b)*") << QString("abac") << 0 << 3
+ QTest::newRow(qPrintable(stri + "star12")) << QString("(?:a|b)*") << QString("c") << 0 << 0 << QStringList();
+ QTest::newRow(qPrintable(stri + "star13")) << QString("(?:a|b)*") << QString("abac") << 0 << 3
<< QStringList();
- QTest::newRow( stri + "star14" ) << QString("(?:a|b|)*") << QString("c") << 0 << 0
+ QTest::newRow(qPrintable(stri + "star14")) << QString("(?:a|b|)*") << QString("c") << 0 << 0
<< QStringList();
- QTest::newRow( stri + "star15" ) << QString("(?:a|b|)*") << QString("abac") << 0 << 3
+ QTest::newRow(qPrintable(stri + "star15")) << QString("(?:a|b|)*") << QString("abac") << 0 << 3
<< QStringList();
- QTest::newRow( stri + "star16" ) << QString("(?:ab|ba|b)*") << QString("abbbababbbaaab") << 0 << 11
+ QTest::newRow(qPrintable(stri + "star16")) << QString("(?:ab|ba|b)*") << QString("abbbababbbaaab") << 0 << 11
<< QStringList();
}
@@ -1373,6 +1374,29 @@ void tst_QRegExp::validityCheck()
QCOMPARE(rx2.cap(), QString(""));
}
+void tst_QRegExp::escapeSequences()
+{
+ QString perlSyntaxSpecialChars("0123456789afnrtvbBdDwWsSx\\|[]{}()^$?+*");
+ QString w3cXmlSchema11SyntaxSpecialChars("cCiIpP"); // as well as the perl ones
+ for (int i = ' '; i <= 127; ++i) {
+ QLatin1Char c(i);
+ if (perlSyntaxSpecialChars.indexOf(c) == -1) {
+ QRegExp rx(QString("\\%1").arg(c), Qt::CaseSensitive, QRegExp::RegExp);
+ // we'll never have c == 'a' since it's a special character
+ QString s = QString("aaa%1aaa").arg(c);
+ QCOMPARE(rx.indexIn(s), 3);
+
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QCOMPARE(rx.indexIn(s), 3);
+
+ if (w3cXmlSchema11SyntaxSpecialChars.indexOf(c) == -1) {
+ rx.setPatternSyntax(QRegExp::W3CXmlSchema11);
+ QCOMPARE(rx.indexIn(s), 3);
+ }
+ }
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QRegExp)
#include "tst_qregexp.moc"
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 7e4f591f47..f007d44262 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -4147,16 +4147,7 @@ void tst_QString::tortureSprintfDouble()
# error "Q_BYTE_ORDER not defined"
# endif
-# ifdef QT_ARMFPA
- buff[0] = data->bytes[4];
- buff[1] = data->bytes[5];
- buff[2] = data->bytes[6];
- buff[3] = data->bytes[7];
- buff[4] = data->bytes[0];
- buff[5] = data->bytes[1];
- buff[6] = data->bytes[2];
- buff[7] = data->bytes[3];
-# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
for (uint i = 0; i < 8; ++i)
buff[i] = data->bytes[i];
# else
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index e1d128dac7..65b68b7f34 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -829,16 +829,8 @@ bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString
QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
if (reply.type() != QDBusMessage::ReplyMessage)
return false;
- if (MyObject::path == path) {
- QTest::compare_helper(true, "COMPARE()", __FILE__, __LINE__);
- } else {
- QTest::compare_helper(false, "Compared values are not the same",
- QTest::toString(MyObject::path), QTest::toString(path),
- "MyObject::path", "path", __FILE__, __LINE__);
- return false;
- }
-
- return true;
+ QTest::qCompare(MyObject::path, path, "MyObject::path", "path", __FILE__, __LINE__);
+ return (MyObject::path == path);
}
bool tst_QDBusConnection::callMethodPeer(const QDBusConnection &conn, const QString &path)
@@ -848,16 +840,8 @@ bool tst_QDBusConnection::callMethodPeer(const QDBusConnection &conn, const QStr
if (reply.type() != QDBusMessage::ReplyMessage)
return false;
- if (MyObject::path == path) {
- QTest::compare_helper(true, "COMPARE()", __FILE__, __LINE__);
- } else {
- QTest::compare_helper(false, "Compared values are not the same",
- QTest::toString(MyObject::path), QTest::toString(path),
- "MyObject::path", "path", __FILE__, __LINE__);
- return false;
- }
-
- return true;
+ QTest::qCompare(MyObject::path, path, "MyObject::path", "path", __FILE__, __LINE__);
+ return (MyObject::path == path);
}
class TestObject : public QObject
diff --git a/tests/auto/gui/image/image.pro b/tests/auto/gui/image/image.pro
index fe089f5e75..fa8f8df29d 100644
--- a/tests/auto/gui/image/image.pro
+++ b/tests/auto/gui/image/image.pro
@@ -9,7 +9,6 @@ SUBDIRS=\
qimageiohandler \
qimagewriter \
qmovie \
- qvolatileimage \
qicon \
qpicture \
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 96171740e2..6f6662a80f 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -772,7 +772,7 @@ void tst_QImageReader::animatedGif()
}
}
-// http://bugreports.qt.nokia.com/browse/QTBUG-6696
+// http://bugreports.qt-project.org/browse/QTBUG-6696
// Check the count of images in various call orders...
void tst_QImageReader::gifImageCount()
{
@@ -1368,7 +1368,7 @@ void tst_QImageReader::readFromResources()
SKIP_IF_UNSUPPORTED(format);
for (int i = 0; i < 2; ++i) {
- QString file = i ? (":/images/" + fileName) : (prefix + fileName);
+ QString file = i ? QString(QStringLiteral(":/images/") + fileName) : QString(prefix + fileName);
{
// suppress warnings if we expect them
if (!message.isEmpty()) {
diff --git a/tests/auto/gui/image/qpixmap/qpixmap.pro b/tests/auto/gui/image/qpixmap/qpixmap.pro
index 91d93a781d..15098770c6 100644
--- a/tests/auto/gui/image/qpixmap/qpixmap.pro
+++ b/tests/auto/gui/image/qpixmap/qpixmap.pro
@@ -10,5 +10,3 @@ SOURCES += tst_qpixmap.cpp
RESOURCES += qpixmap.qrc
TESTDATA += convertFromImage/* convertFromToHICON/* loadFromData/* images/*
-
-win32:CONFIG += insignificant_test # QTBUG-24183
diff --git a/tests/auto/gui/image/qvolatileimage/qvolatileimage.pro b/tests/auto/gui/image/qvolatileimage/qvolatileimage.pro
deleted file mode 100644
index 3d982d7951..0000000000
--- a/tests/auto/gui/image/qvolatileimage/qvolatileimage.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qvolatileimage
-
-QT += gui-private widgets testlib
-
-SOURCES += tst_qvolatileimage.cpp
diff --git a/tests/auto/gui/image/qvolatileimage/tst_qvolatileimage.cpp b/tests/auto/gui/image/qvolatileimage/tst_qvolatileimage.cpp
deleted file mode 100644
index f203cfec0f..0000000000
--- a/tests/auto/gui/image/qvolatileimage/tst_qvolatileimage.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpaintengine.h>
-#include <QtGui/private/qvolatileimage_p.h>
-
-class tst_QVolatileImage : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QVolatileImage() { }
-
-private slots:
- void create();
- void ensureFormat();
- void dataAccess();
- void sharing();
- void fill();
- void copy();
-};
-
-void tst_QVolatileImage::create()
-{
- QVolatileImage nullImg;
- QVERIFY(nullImg.isNull());
-
- QVolatileImage img(100, 200, QImage::Format_ARGB32);
- QVERIFY(!img.isNull());
- QCOMPARE(img.width(), 100);
- QCOMPARE(img.height(), 200);
- QCOMPARE(img.format(), QImage::Format_ARGB32);
- QCOMPARE(img.byteCount(), img.bytesPerLine() * img.height());
- QCOMPARE(img.hasAlphaChannel(), true);
- QCOMPARE(img.depth(), 32);
-
- QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
- img = QVolatileImage(source);
- QVERIFY(!img.isNull());
- QCOMPARE(img.width(), 12);
- QCOMPARE(img.height(), 23);
- QCOMPARE(img.format(), source.format());
- QCOMPARE(img.byteCount(), img.bytesPerLine() * img.height());
- QVERIFY(img.imageRef() == source);
- QVERIFY(img.toImage() == source);
- QCOMPARE(img.hasAlphaChannel(), true);
- QCOMPARE(img.hasAlphaChannel(), img.imageRef().hasAlphaChannel());
- QCOMPARE(img.hasAlphaChannel(), img.toImage().hasAlphaChannel());
- QCOMPARE(img.depth(), 32);
-}
-
-void tst_QVolatileImage::ensureFormat()
-{
- QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
- QVolatileImage img(source);
- QVERIFY(!img.isNull());
- QVERIFY(img.imageRef() == source);
- QVERIFY(img.toImage() == source);
-
- QVERIFY(img.ensureFormat(QImage::Format_ARGB32_Premultiplied)); // no-op
- QVERIFY(img.imageRef() == source);
- QVERIFY(img.toImage() == source);
- QVERIFY(img.format() == QImage::Format_ARGB32_Premultiplied);
-
- QVERIFY(img.ensureFormat(QImage::Format_RGB32)); // new data under-the-hood
- QVERIFY(img.imageRef() != source);
- QVERIFY(img.toImage() != source);
- QVERIFY(img.format() == QImage::Format_RGB32);
-}
-
-void tst_QVolatileImage::dataAccess()
-{
- QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
- QVolatileImage img(source);
- QVERIFY(!img.isNull());
- img.beginDataAccess();
- QVERIFY(img.constBits());
- QVERIFY(img.imageRef().constBits());
- QVERIFY(img.bits());
- QVERIFY(img.imageRef().bits());
- img.endDataAccess();
-
- img = QVolatileImage(12, 23, QImage::Format_ARGB32);
- img.beginDataAccess();
- QVERIFY(img.constBits() && img.bits());
- img.endDataAccess();
-}
-
-void tst_QVolatileImage::sharing()
-{
- QVolatileImage img1(100, 100, QImage::Format_ARGB32);
- QVolatileImage img2 = img1;
- img1.beginDataAccess();
- img2.beginDataAccess();
- QVERIFY(img1.constBits() == img2.constBits());
- img2.endDataAccess();
- img1.endDataAccess();
- img1.imageRef(); // non-const call, should detach
- img1.beginDataAccess();
- img2.beginDataAccess();
- QVERIFY(img1.constBits() != img2.constBits());
- img2.endDataAccess();
- img1.endDataAccess();
-
- // toImage() should return a copy of the internal QImage.
- // imageRef() is a reference to the internal QImage.
- QVERIFY(img1.imageRef().constBits() != img1.toImage().constBits());
-}
-
-bool fuzzyCompareImages(const QImage &image1, const QImage &image2, int tolerance)
-{
- if (image1.bytesPerLine() != image2.bytesPerLine()
- || image1.width() != image2.width()
- || image1.height() != image2.height()) {
- return false;
- }
- for (int i = 0; i < image1.height(); i++) {
- const uchar *line1 = image1.scanLine(i);
- const uchar *line2 = image2.scanLine(i);
- int bytes = image1.bytesPerLine();
- for (int j = 0; j < bytes; j++) {
- int delta = line1[j] - line2[j];
- if (qAbs(delta) > tolerance)
- return false;
- }
- }
- return true;
-}
-
-void tst_QVolatileImage::fill()
-{
- QVolatileImage img(100, 100, QImage::Format_ARGB32_Premultiplied);
- QColor col = QColor(10, 20, 30);
- img.fill(col.rgba());
- QVERIFY(img.imageRef().pixel(1, 1) == col.rgba());
- QVERIFY(img.toImage().pixel(1, 1) == col.rgba());
-}
-
-void tst_QVolatileImage::copy()
-{
- QVolatileImage img(100, 100, QImage::Format_RGB32);
- img.beginDataAccess();
- img.imageRef().fill(QColor(Qt::green).rgba());
- QPainter p(&img.imageRef());
- p.drawRect(10, 10, 50, 50);
- p.end();
- img.endDataAccess();
-
- QVolatileImage img2(100, 100, QImage::Format_RGB32);
- img2.copyFrom(&img, QRect());
- QImage imgA = img.toImage();
- QImage imgB = img2.toImage();
- QCOMPARE(imgA.size(), imgB.size());
- QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
-
- img2 = QVolatileImage(20, 20, QImage::Format_RGB32);
- img2.copyFrom(&img, QRect(5, 5, 20, 20));
- imgA = img.toImage().copy(5, 5, 20, 20);
- imgB = img2.toImage();
- QCOMPARE(imgA.size(), imgB.size());
- QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
-}
-
-QTEST_MAIN(tst_QVolatileImage)
-#include "tst_qvolatileimage.moc"
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 90c96b4030..f4556f7e32 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -64,6 +64,8 @@ private slots:
void touchCancelWithTouchToMouse();
void orientation();
void close();
+ void activateAndClose();
+
void initTestCase()
{
touchDevice = new QTouchDevice;
@@ -632,5 +634,16 @@ void tst_QWindow::close()
QVERIFY(b.close());
}
+void tst_QWindow::activateAndClose()
+{
+ for (int i = 0; i < 10; ++i) {
+ QWindow window;
+ window.show();
+ QTest::qWaitForWindowShown(&window);
+ window.requestActivateWindow();
+ QTRY_COMPARE(qGuiApp->focusWindow(), &window);
+ }
+}
+
#include <tst_qwindow.moc>
QTEST_MAIN(tst_QWindow);
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index 7c9a83eaa4..a88e93c93e 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -1283,6 +1283,9 @@ void tst_QTextScriptEngine::thaiIsolatedSaraAm()
void tst_QTextScriptEngine::thaiWithZWJ()
{
+#ifdef Q_OS_WIN
+ QSKIP("This test currently fails on Windows - QTBUG-24565");
+#endif
QString s(QString::fromUtf8("ร‍ร‌.ร.“ร…ร”ร\xA0ร本ร") + QChar(0x0363)/*superscript 'a', for testing Inherited class*/);
QTextLayout layout(s);
layout.beginLayout();
diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
index 0e046ad6f9..5dffe68386 100644
--- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
+++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
@@ -278,6 +278,8 @@ void tst_QNetworkCookieJar::cookiesForUrl_data()
QTest::newRow("no-match-5") << allCookies << "http://qt.nokia.com" << result;
QTest::newRow("no-match-6") << allCookies << "http://nokia.com/webinar" << result;
QTest::newRow("no-match-7") << allCookies << "http://qt.nokia.com/webinar" << result;
+ QTest::newRow("no-match-8") << allCookies << "http://qt.nokia.com./web" << result;
+ QTest::newRow("no-match-9") << allCookies << "http://nokia.com./web" << result;
result = allCookies;
QTest::newRow("match-1") << allCookies << "http://nokia.com/web" << result;
@@ -350,6 +352,16 @@ void tst_QNetworkCookieJar::cookiesForUrl_data()
QTest::newRow("match-secure-1") << allCookies << "https://nokia.com/web" << result;
QTest::newRow("match-secure-2") << allCookies << "https://qt.nokia.com/web" << result;
+ // domain ending in .
+ allCookies.clear();
+ result.clear();
+ QNetworkCookie cookieDot;
+ cookieDot.setDomain(".example.com.");
+ cookieDot.setName("a");
+ allCookies += cookieDot;
+ QTest::newRow("no-match-domain-dot") << allCookies << "http://example.com" << result;
+ result += cookieDot;
+ QTest::newRow("match-domain-dot") << allCookies << "http://example.com." << result;
}
void tst_QNetworkCookieJar::cookiesForUrl()
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 5b34fa7c29..d8f9bf32ad 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -6474,7 +6474,7 @@ void tst_QNetworkReply::synchronousRequest()
// workaround for HTTPS requests: add self-signed server cert to list of CA certs,
// since we cannot react to the sslErrors() signal
// to fix this properly we would need to have an ignoreSslErrors() method in the
- // QNetworkRequest, see http://bugreports.qt.nokia.com/browse/QTBUG-14774
+ // QNetworkRequest, see http://bugreports.qt-project.org/browse/QTBUG-14774
if (url.scheme() == "https") {
QSslConfiguration sslConf;
QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
diff --git a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp
index 3baca3c50b..249ccd3d75 100644
--- a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp
+++ b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp
@@ -139,7 +139,7 @@ void tst_QDnsLookup::lookup()
lookup.lookup();
QVERIFY(waitForDone(&lookup));
QVERIFY(lookup.isFinished());
- QCOMPARE(int(lookup.error()), error);
+ QVERIFY2(int(lookup.error()) == error, qPrintable(lookup.errorString()));
if (error == QDnsLookup::NoError)
QVERIFY(lookup.errorString().isEmpty());
QCOMPARE(int(lookup.type()), type);
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 08938be4d1..5395c7c28b 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -201,6 +201,8 @@ private slots:
void qtbug14268_peek();
+ void setSocketOption();
+
protected slots:
void nonBlockingIMAP_hostFound();
@@ -2699,7 +2701,41 @@ void tst_QTcpSocket::qtbug14268_peek()
QVERIFY(incoming->read(128*1024) == QByteArray("abc\ndef\nghi\n"));
}
+void tst_QTcpSocket::setSocketOption()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy)
+ return;
+
+ SocketPair socketPair;
+ QVERIFY(socketPair.create());
+ QTcpSocket *outgoing = socketPair.endPoints[0];
+ QTcpSocket *incoming = socketPair.endPoints[1];
+
+ QVERIFY(incoming->state() == QTcpSocket::ConnectedState);
+ QVERIFY(outgoing->state() == QTcpSocket::ConnectedState);
+
+ outgoing->setSocketOption(QAbstractSocket::LowDelayOption, true);
+ QVariant v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
+ QVERIFY(v.isValid() && v.toBool());
+ outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, true);
+ v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
+ QVERIFY(v.isValid() && v.toBool());
+ outgoing->setSocketOption(QAbstractSocket::LowDelayOption, false);
+ v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
+ QVERIFY(v.isValid() && !v.toBool());
+ outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, false);
+ v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
+ QVERIFY(v.isValid() && !v.toBool());
+
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "QTBUG-23323", Abort);
+#endif
+ outgoing->setSocketOption(QAbstractSocket::TypeOfServiceOption, 32); //high priority
+ v = outgoing->socketOption(QAbstractSocket::TypeOfServiceOption);
+ QVERIFY(v.isValid() && v.toInt() == 32);
+}
QTEST_MAIN(tst_QTcpSocket)
#include "tst_qtcpsocket.moc"
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp
index d72a04c8aa..1f461ba10b 100644
--- a/tests/auto/other/compiler/tst_compiler.cpp
+++ b/tests/auto/other/compiler/tst_compiler.cpp
@@ -525,33 +525,23 @@ void tst_Compiler::privateStaticTemplateMember() const
// the second member of the union
static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } };
static inline double qt_inf()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_inf_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes.d
: qt_le_inf_bytes.d);
-#endif
}
#else
static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
-static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
static inline double qt_inf()
{
const uchar *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_inf_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes
: qt_le_inf_bytes);
-#endif
union { uchar c[8]; double d; } returnValue;
memcpy(returnValue.c, bytes, sizeof(returnValue.c));
diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp
index 841df6e1f0..ebb8443748 100644
--- a/tests/auto/other/networkselftest/tst_networkselftest.cpp
+++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp
@@ -938,7 +938,7 @@ void tst_NetworkSelfTest::socks5ProxyAuth()
void tst_NetworkSelfTest::supportsSsl()
{
#ifdef QT_NO_SSL
- QFAIL("SSL not compiled in");
+ QSKIP("SSL not compiled in");
#else
QVERIFY2(QSslSocket::supportsSsl(), "Could not load SSL libraries");
#endif
diff --git a/tests/auto/testlib/selftests/counting/tst_counting.cpp b/tests/auto/testlib/selftests/counting/tst_counting.cpp
index fa61fce173..9c3dd48015 100644
--- a/tests/auto/testlib/selftests/counting/tst_counting.cpp
+++ b/tests/auto/testlib/selftests/counting/tst_counting.cpp
@@ -109,6 +109,7 @@ void tst_Counting::helper()
switch (result) {
case Pass:
QVERIFY(true);
+ QCOMPARE(2 + 1, 3);
break;
case Fail:
QVERIFY(false);
diff --git a/tests/auto/testlib/selftests/expected_counting.lightxml b/tests/auto/testlib/selftests/expected_counting.lightxml
index e7b1136417..c49792fec4 100644
--- a/tests/auto/testlib/selftests/expected_counting.lightxml
+++ b/tests/auto/testlib/selftests/expected_counting.lightxml
@@ -17,7 +17,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 1]]></DataTag>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
@@ -26,13 +26,13 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 1]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
@@ -41,27 +41,27 @@
</Incident>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
@@ -70,21 +70,21 @@
</Incident>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
@@ -93,7 +93,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[before]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="233">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[Fail in init()]]></Description>
</Incident>
@@ -109,7 +109,7 @@
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="241">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[Fail in cleanup()]]></Description>
</Incident>
@@ -121,7 +121,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[before]]></DataTag>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="235">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[Skip in init()]]></Description>
</Message>
@@ -137,7 +137,7 @@
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="243">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[Skip in cleanup()]]></Description>
</Message>
diff --git a/tests/auto/testlib/selftests/expected_counting.txt b/tests/auto/testlib/selftests/expected_counting.txt
index 5c17e3c257..3245d9d7be 100644
--- a/tests/auto/testlib/selftests/expected_counting.txt
+++ b/tests/auto/testlib/selftests/expected_counting.txt
@@ -5,49 +5,49 @@ PASS : tst_Counting::testPassPass(row 1)
PASS : tst_Counting::testPassPass(row 2)
PASS : tst_Counting::testPassSkip(row 1)
SKIP : tst_Counting::testPassSkip(row 2) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
PASS : tst_Counting::testPassFail(row 1)
FAIL! : tst_Counting::testPassFail(row 2) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
SKIP : tst_Counting::testSkipPass(row 1) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
PASS : tst_Counting::testSkipPass(row 2)
SKIP : tst_Counting::testSkipSkip(row 1) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
SKIP : tst_Counting::testSkipSkip(row 2) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
SKIP : tst_Counting::testSkipFail(row 1) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
FAIL! : tst_Counting::testSkipFail(row 2) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
FAIL! : tst_Counting::testFailPass(row 1) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
PASS : tst_Counting::testFailPass(row 2)
FAIL! : tst_Counting::testFailSkip(row 1) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
SKIP : tst_Counting::testFailSkip(row 2) Skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
FAIL! : tst_Counting::testFailFail(row 1) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
FAIL! : tst_Counting::testFailFail(row 2) 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
PASS : tst_Counting::testFailInInit(before)
FAIL! : tst_Counting::testFailInInit(fail) Fail in init()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(233)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(234)]
PASS : tst_Counting::testFailInInit(after)
PASS : tst_Counting::testFailInCleanup(before)
QDEBUG : tst_Counting::testFailInCleanup(fail) This test function should execute and then QFAIL in cleanup()
FAIL! : tst_Counting::testFailInCleanup(fail) Fail in cleanup()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(241)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(242)]
PASS : tst_Counting::testFailInCleanup(after)
PASS : tst_Counting::testSkipInInit(before)
SKIP : tst_Counting::testSkipInInit(skip) Skip in init()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(235)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(236)]
PASS : tst_Counting::testSkipInInit(after)
PASS : tst_Counting::testSkipInCleanup(before)
QDEBUG : tst_Counting::testSkipInCleanup(skip) This test function should execute and then QSKIP in cleanup()
SKIP : tst_Counting::testSkipInCleanup(skip) Skip in cleanup()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(243)]
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(244)]
PASS : tst_Counting::testSkipInCleanup(after)
PASS : tst_Counting::cleanupTestCase()
Totals: 16 passed, 8 failed, 8 skipped
diff --git a/tests/auto/testlib/selftests/expected_counting.xml b/tests/auto/testlib/selftests/expected_counting.xml
index a97296807d..7ed93b9c73 100644
--- a/tests/auto/testlib/selftests/expected_counting.xml
+++ b/tests/auto/testlib/selftests/expected_counting.xml
@@ -19,7 +19,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 1]]></DataTag>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
@@ -28,13 +28,13 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 1]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
@@ -43,27 +43,27 @@
</Incident>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
@@ -72,21 +72,21 @@
</Incident>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="117">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="114">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
@@ -95,7 +95,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[before]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="233">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[Fail in init()]]></Description>
</Incident>
@@ -111,7 +111,7 @@
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="241">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
<DataTag><![CDATA[fail]]></DataTag>
<Description><![CDATA[Fail in cleanup()]]></Description>
</Incident>
@@ -123,7 +123,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[before]]></DataTag>
</Incident>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="235">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[Skip in init()]]></Description>
</Message>
@@ -139,7 +139,7 @@
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="243">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
<DataTag><![CDATA[skip]]></DataTag>
<Description><![CDATA[Skip in cleanup()]]></Description>
</Message>
diff --git a/tests/auto/testlib/selftests/expected_fatal.txt b/tests/auto/testlib/selftests/expected_fatal.txt
deleted file mode 100644
index a525fee0a1..0000000000
--- a/tests/auto/testlib/selftests/expected_fatal.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-********* Start testing of tst_Fatal *********
-Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
-PASS : tst_Fatal::initTestCase()
-QFATAL : tst_Fatal::testFunction() A fatal error occured! Ouuiieee!! The world is coming to an end and I will die! Buhu!
-Totals: 1 passed, 0 failed, 0 skipped
-********* Finished testing of tst_Fatal *********
diff --git a/tests/auto/testlib/selftests/expected_verbose1.lightxml b/tests/auto/testlib/selftests/expected_verbose1.lightxml
new file mode 100644
index 0000000000..c49792fec4
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose1.lightxml
@@ -0,0 +1,150 @@
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+<TestFunction name="testPassPass">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testPassSkip">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testPassFail">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipPass">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipSkip">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testSkipFail">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailPass">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailSkip">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testFailFail">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in init()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in cleanup()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in init()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in cleanup()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.txt b/tests/auto/testlib/selftests/expected_verbose1.txt
new file mode 100644
index 0000000000..0286f719aa
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose1.txt
@@ -0,0 +1,69 @@
+********* Start testing of tst_Counting *********
+Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
+INFO : tst_Counting::initTestCase() entering
+PASS : tst_Counting::initTestCase()
+INFO : tst_Counting::testPassPass() entering
+PASS : tst_Counting::testPassPass(row 1)
+PASS : tst_Counting::testPassPass(row 2)
+INFO : tst_Counting::testPassSkip() entering
+PASS : tst_Counting::testPassSkip(row 1)
+SKIP : tst_Counting::testPassSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testPassFail() entering
+PASS : tst_Counting::testPassFail(row 1)
+FAIL! : tst_Counting::testPassFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testSkipPass() entering
+SKIP : tst_Counting::testSkipPass(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+PASS : tst_Counting::testSkipPass(row 2)
+INFO : tst_Counting::testSkipSkip() entering
+SKIP : tst_Counting::testSkipSkip(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+SKIP : tst_Counting::testSkipSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testSkipFail() entering
+SKIP : tst_Counting::testSkipFail(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+FAIL! : tst_Counting::testSkipFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailPass() entering
+FAIL! : tst_Counting::testFailPass(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+PASS : tst_Counting::testFailPass(row 2)
+INFO : tst_Counting::testFailSkip() entering
+FAIL! : tst_Counting::testFailSkip(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+SKIP : tst_Counting::testFailSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testFailFail() entering
+FAIL! : tst_Counting::testFailFail(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testFailFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailInInit() entering
+PASS : tst_Counting::testFailInInit(before)
+FAIL! : tst_Counting::testFailInInit(fail) Fail in init()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(234)]
+PASS : tst_Counting::testFailInInit(after)
+INFO : tst_Counting::testFailInCleanup() entering
+PASS : tst_Counting::testFailInCleanup(before)
+QDEBUG : tst_Counting::testFailInCleanup(fail) This test function should execute and then QFAIL in cleanup()
+FAIL! : tst_Counting::testFailInCleanup(fail) Fail in cleanup()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(242)]
+PASS : tst_Counting::testFailInCleanup(after)
+INFO : tst_Counting::testSkipInInit() entering
+PASS : tst_Counting::testSkipInInit(before)
+SKIP : tst_Counting::testSkipInInit(skip) Skip in init()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(236)]
+PASS : tst_Counting::testSkipInInit(after)
+INFO : tst_Counting::testSkipInCleanup() entering
+PASS : tst_Counting::testSkipInCleanup(before)
+QDEBUG : tst_Counting::testSkipInCleanup(skip) This test function should execute and then QSKIP in cleanup()
+SKIP : tst_Counting::testSkipInCleanup(skip) Skip in cleanup()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(244)]
+PASS : tst_Counting::testSkipInCleanup(after)
+INFO : tst_Counting::cleanupTestCase() entering
+PASS : tst_Counting::cleanupTestCase()
+Totals: 16 passed, 8 failed, 8 skipped
+********* Finished testing of tst_Counting *********
diff --git a/tests/auto/testlib/selftests/expected_verbose1.xml b/tests/auto/testlib/selftests/expected_verbose1.xml
new file mode 100644
index 0000000000..7ed93b9c73
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose1.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<TestCase name="tst_Counting">
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+<TestFunction name="testPassPass">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testPassSkip">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testPassFail">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipPass">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipSkip">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testSkipFail">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailPass">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailSkip">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testFailFail">
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in init()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in cleanup()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in init()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in cleanup()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.xunitxml b/tests/auto/testlib/selftests/expected_verbose1.xunitxml
new file mode 100644
index 0000000000..f317ed5923
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose1.xunitxml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite errors="10" failures="8" tests="15" name="tst_Counting">
+ <properties>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
+ </properties>
+ <testcase result="pass" name="initTestCase"/>
+ <testcase result="pass" name="testPassPass"/>
+ <testcase result="pass" name="testPassSkip">
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testPassFail">
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="testSkipPass">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase name="testSkipSkip">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testSkipFail">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailPass">
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailSkip">
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testFailFail">
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailInInit">
+ <failure tag="fail" message="Fail in init()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailInCleanup">
+ <!-- tag="fail" message="This test function should execute and then QFAIL in cleanup() " type="qdebug" -->
+ <failure tag="fail" message="Fail in cleanup()" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="testSkipInInit">
+ <!-- tag="skip" message="Skip in init()" type="skip" -->
+ </testcase>
+ <testcase result="pass" name="testSkipInCleanup">
+ <!-- tag="skip" message="This test function should execute and then QSKIP in cleanup() " type="qdebug" -->
+ <!-- tag="skip" message="Skip in cleanup()" type="skip" -->
+ </testcase>
+ <testcase result="pass" name="cleanupTestCase"/>
+ <system-err>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[This test function should execute and then QFAIL in cleanup() ]]>
+<![CDATA[Skip in init()]]>
+<![CDATA[This test function should execute and then QSKIP in cleanup() ]]>
+<![CDATA[Skip in cleanup()]]>
+ </system-err>
+</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_verbose2.lightxml b/tests/auto/testlib/selftests/expected_verbose2.lightxml
new file mode 100644
index 0000000000..1310f2bb09
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose2.lightxml
@@ -0,0 +1,222 @@
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+<TestFunction name="testPassPass">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testPassSkip">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testPassFail">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipPass">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipSkip">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testSkipFail">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailPass">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailSkip">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testFailFail">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in init()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in cleanup()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in init()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in cleanup()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_verbose2.txt b/tests/auto/testlib/selftests/expected_verbose2.txt
new file mode 100644
index 0000000000..9012a7c569
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose2.txt
@@ -0,0 +1,105 @@
+********* Start testing of tst_Counting *********
+Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
+INFO : tst_Counting::initTestCase() entering
+PASS : tst_Counting::initTestCase()
+INFO : tst_Counting::testPassPass() entering
+INFO : tst_Counting::testPassPass(row 1) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testPassPass(row 1) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testPassPass(row 1)
+INFO : tst_Counting::testPassPass(row 2) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testPassPass(row 2) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testPassPass(row 2)
+INFO : tst_Counting::testPassSkip() entering
+INFO : tst_Counting::testPassSkip(row 1) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testPassSkip(row 1) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testPassSkip(row 1)
+SKIP : tst_Counting::testPassSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testPassFail() entering
+INFO : tst_Counting::testPassFail(row 1) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testPassFail(row 1) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testPassFail(row 1)
+INFO : tst_Counting::testPassFail(row 2) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testPassFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testSkipPass() entering
+SKIP : tst_Counting::testSkipPass(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testSkipPass(row 2) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testSkipPass(row 2) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testSkipPass(row 2)
+INFO : tst_Counting::testSkipSkip() entering
+SKIP : tst_Counting::testSkipSkip(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+SKIP : tst_Counting::testSkipSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testSkipFail() entering
+SKIP : tst_Counting::testSkipFail(row 1) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testSkipFail(row 2) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testSkipFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailPass() entering
+INFO : tst_Counting::testFailPass(row 1) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testFailPass(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailPass(row 2) QVERIFY(true)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(111)]
+INFO : tst_Counting::testFailPass(row 2) COMPARE()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+PASS : tst_Counting::testFailPass(row 2)
+INFO : tst_Counting::testFailSkip() entering
+INFO : tst_Counting::testFailSkip(row 1) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testFailSkip(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+SKIP : tst_Counting::testFailSkip(row 2) Skipping
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(118)]
+INFO : tst_Counting::testFailFail() entering
+INFO : tst_Counting::testFailFail(row 1) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testFailFail(row 1) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailFail(row 2) QVERIFY(false)
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+FAIL! : tst_Counting::testFailFail(row 2) 'false' returned FALSE. ()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(115)]
+INFO : tst_Counting::testFailInInit() entering
+PASS : tst_Counting::testFailInInit(before)
+FAIL! : tst_Counting::testFailInInit(fail) Fail in init()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(234)]
+PASS : tst_Counting::testFailInInit(after)
+INFO : tst_Counting::testFailInCleanup() entering
+PASS : tst_Counting::testFailInCleanup(before)
+QDEBUG : tst_Counting::testFailInCleanup(fail) This test function should execute and then QFAIL in cleanup()
+FAIL! : tst_Counting::testFailInCleanup(fail) Fail in cleanup()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(242)]
+PASS : tst_Counting::testFailInCleanup(after)
+INFO : tst_Counting::testSkipInInit() entering
+PASS : tst_Counting::testSkipInInit(before)
+SKIP : tst_Counting::testSkipInInit(skip) Skip in init()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(236)]
+PASS : tst_Counting::testSkipInInit(after)
+INFO : tst_Counting::testSkipInCleanup() entering
+PASS : tst_Counting::testSkipInCleanup(before)
+QDEBUG : tst_Counting::testSkipInCleanup(skip) This test function should execute and then QSKIP in cleanup()
+SKIP : tst_Counting::testSkipInCleanup(skip) Skip in cleanup()
+ Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(244)]
+PASS : tst_Counting::testSkipInCleanup(after)
+INFO : tst_Counting::cleanupTestCase() entering
+PASS : tst_Counting::cleanupTestCase()
+Totals: 16 passed, 8 failed, 8 skipped
+********* Finished testing of tst_Counting *********
diff --git a/tests/auto/testlib/selftests/expected_verbose2.xml b/tests/auto/testlib/selftests/expected_verbose2.xml
new file mode 100644
index 0000000000..693ef2b187
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose2.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<TestCase name="tst_Counting">
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+<TestFunction name="testPassPass">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testPassSkip">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testPassFail">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 1]]></DataTag>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipPass">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipSkip">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testSkipFail">
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailPass">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(true)]]></Description>
+</Message>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="112">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[COMPARE()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[row 2]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailSkip">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[Skipping]]></Description>
+</Message>
+</TestFunction>
+<TestFunction name="testFailFail">
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 1]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA[QVERIFY(false)]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+ <DataTag><![CDATA[row 2]]></DataTag>
+ <Description><![CDATA['false' returned FALSE. ()]]></Description>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="234">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in init()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testFailInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+</Message>
+<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="242">
+ <DataTag><![CDATA[fail]]></DataTag>
+ <Description><![CDATA[Fail in cleanup()]]></Description>
+</Incident>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInInit">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="236">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in init()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="testSkipInCleanup">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[before]]></DataTag>
+</Incident>
+<Message type="qdebug" file="" line="0">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+</Message>
+<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="244">
+ <DataTag><![CDATA[skip]]></DataTag>
+ <Description><![CDATA[Skip in cleanup()]]></Description>
+</Message>
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[after]]></DataTag>
+</Incident>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+</TestFunction>
+</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_verbose2.xunitxml b/tests/auto/testlib/selftests/expected_verbose2.xunitxml
new file mode 100644
index 0000000000..8b9ed5257d
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose2.xunitxml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite errors="28" failures="8" tests="15" name="tst_Counting">
+ <properties>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
+ </properties>
+ <testcase result="pass" name="initTestCase"/>
+ <testcase result="pass" name="testPassPass">
+ <!-- tag="row 1" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 1" message="COMPARE()" type="info" -->
+ <!-- tag="row 2" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 2" message="COMPARE()" type="info" -->
+ </testcase>
+ <testcase result="pass" name="testPassSkip">
+ <!-- tag="row 1" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 1" message="COMPARE()" type="info" -->
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testPassFail">
+ <!-- tag="row 1" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 1" message="COMPARE()" type="info" -->
+ <!-- tag="row 2" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="testSkipPass">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ <!-- tag="row 2" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 2" message="COMPARE()" type="info" -->
+ </testcase>
+ <testcase name="testSkipSkip">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testSkipFail">
+ <!-- tag="row 1" message="Skipping" type="skip" -->
+ <!-- tag="row 2" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailPass">
+ <!-- tag="row 1" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ <!-- tag="row 2" message="QVERIFY(true)" type="info" -->
+ <!-- tag="row 2" message="COMPARE()" type="info" -->
+ </testcase>
+ <testcase result="fail" name="testFailSkip">
+ <!-- tag="row 1" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ <!-- tag="row 2" message="Skipping" type="skip" -->
+ </testcase>
+ <testcase result="fail" name="testFailFail">
+ <!-- tag="row 1" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 1" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ <!-- tag="row 2" message="QVERIFY(false)" type="info" -->
+ <failure tag="row 2" message="&apos;false&apos; returned FALSE. ()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailInInit">
+ <failure tag="fail" message="Fail in init()" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailInCleanup">
+ <!-- tag="fail" message="This test function should execute and then QFAIL in cleanup() " type="qdebug" -->
+ <failure tag="fail" message="Fail in cleanup()" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="testSkipInInit">
+ <!-- tag="skip" message="Skip in init()" type="skip" -->
+ </testcase>
+ <testcase result="pass" name="testSkipInCleanup">
+ <!-- tag="skip" message="This test function should execute and then QSKIP in cleanup() " type="qdebug" -->
+ <!-- tag="skip" message="Skip in cleanup()" type="skip" -->
+ </testcase>
+ <testcase result="pass" name="cleanupTestCase"/>
+ <system-err>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[Skipping]]>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[Skipping]]>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[Skipping]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[QVERIFY(true)]]>
+<![CDATA[COMPARE()]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[Skipping]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[QVERIFY(false)]]>
+<![CDATA[This test function should execute and then QFAIL in cleanup() ]]>
+<![CDATA[Skip in init()]]>
+<![CDATA[This test function should execute and then QSKIP in cleanup() ]]>
+<![CDATA[Skip in cleanup()]]>
+ </system-err>
+</testsuite>
diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri
index 1fc66e6364..c9474419eb 100644
--- a/tests/auto/testlib/selftests/selftests.pri
+++ b/tests/auto/testlib/selftests/selftests.pri
@@ -39,5 +39,7 @@ SUBPROGRAMS = \
sleep \
strcmp \
subtest \
+ verbose1 \
+ verbose2 \
warnings \
xunit
diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc
index d05ac2a516..03de05fb89 100644
--- a/tests/auto/testlib/selftests/selftests.qrc
+++ b/tests/auto/testlib/selftests/selftests.qrc
@@ -71,11 +71,14 @@
<file>expected_failinitdata.txt</file>
<file>expected_failinitdata.xml</file>
<file>expected_failinitdata.xunitxml</file>
- <file>expected_fatal.txt</file>
<file>expected_fetchbogus.lightxml</file>
<file>expected_fetchbogus.txt</file>
<file>expected_fetchbogus.xml</file>
<file>expected_fetchbogus.xunitxml</file>
+ <file>expected_findtestdata.lightxml</file>
+ <file>expected_findtestdata.txt</file>
+ <file>expected_findtestdata.xml</file>
+ <file>expected_findtestdata.xunitxml</file>
<file>expected_float.txt</file>
<file>expected_globaldata.lightxml</file>
<file>expected_globaldata.txt</file>
@@ -123,10 +126,14 @@
<file>expected_subtest.txt</file>
<file>expected_subtest.xml</file>
<file>expected_subtest.xunitxml</file>
- <file>expected_findtestdata.lightxml</file>
- <file>expected_findtestdata.txt</file>
- <file>expected_findtestdata.xml</file>
- <file>expected_findtestdata.xunitxml</file>
+ <file>expected_verbose1.lightxml</file>
+ <file>expected_verbose1.txt</file>
+ <file>expected_verbose1.xml</file>
+ <file>expected_verbose1.xunitxml</file>
+ <file>expected_verbose2.lightxml</file>
+ <file>expected_verbose2.txt</file>
+ <file>expected_verbose2.xml</file>
+ <file>expected_verbose2.xunitxml</file>
<file>expected_warnings.lightxml</file>
<file>expected_warnings.txt</file>
<file>expected_warnings.xml</file>
diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp
index 2b90bdb389..5d216992d7 100644
--- a/tests/auto/testlib/selftests/tst_selftests.cpp
+++ b/tests/auto/testlib/selftests/tst_selftests.cpp
@@ -346,6 +346,7 @@ void tst_Selftests::runSubTest_data()
// Disable this test on Windows, as the run-time will popup dialogs with warnings
<< "fetchbogus"
#endif
+ << "findtestdata"
<< "float"
<< "globaldata"
<< "longstring"
@@ -363,7 +364,8 @@ void tst_Selftests::runSubTest_data()
<< "sleep"
<< "strcmp"
<< "subtest"
- << "findtestdata"
+ << "verbose1"
+ << "verbose2"
<< "warnings"
<< "xunit"
;
@@ -413,6 +415,12 @@ void tst_Selftests::runSubTest_data()
else if (subtest == "silent") {
arguments << "-silent";
}
+ else if (subtest == "verbose1") {
+ arguments << "-v1";
+ }
+ else if (subtest == "verbose2") {
+ arguments << "-v2";
+ }
// These tests don't work right unless logging plain text to
diff --git a/tests/auto/testlib/selftests/verbose1/verbose1.pro b/tests/auto/testlib/selftests/verbose1/verbose1.pro
new file mode 100644
index 0000000000..f00ae69d17
--- /dev/null
+++ b/tests/auto/testlib/selftests/verbose1/verbose1.pro
@@ -0,0 +1,10 @@
+# This test just reuses the counting selftest to show how the output
+# differs when the -v1 command-line switch is used.
+
+SOURCES += ../counting/tst_counting.cpp
+QT = core testlib
+
+mac:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+
+TARGET = verbose1
diff --git a/tests/auto/testlib/selftests/verbose2/verbose2.pro b/tests/auto/testlib/selftests/verbose2/verbose2.pro
new file mode 100644
index 0000000000..796cdeb975
--- /dev/null
+++ b/tests/auto/testlib/selftests/verbose2/verbose2.pro
@@ -0,0 +1,10 @@
+# This test just reuses the counting selftest to show how the output
+# differs when the -v2 command-line switch is used.
+
+SOURCES += ../counting/tst_counting.cpp
+QT = core testlib
+
+mac:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+
+TARGET = verbose2
diff --git a/tests/auto/tools/qmake/testcompiler.cpp b/tests/auto/tools/qmake/testcompiler.cpp
index 97c640b28f..4e5dc26eac 100644
--- a/tests/auto/tools/qmake/testcompiler.cpp
+++ b/tests/auto/tools/qmake/testcompiler.cpp
@@ -132,13 +132,34 @@ bool TestCompiler::errorOut()
return false;
}
+// Return the system environment, remove MAKEFLAGS variable in
+// case the CI uses jom passing flags incompatible to nmake
+// or vice versa.
+static inline QStringList systemEnvironment()
+{
+#ifdef Q_OS_WIN
+ static QStringList result;
+ if (result.isEmpty()) {
+ foreach (const QString &variable, QProcess::systemEnvironment()) {
+ if (variable.startsWith(QStringLiteral("MAKEFLAGS="), Qt::CaseInsensitive)) {
+ qWarning("Removing environment setting '%s'", qPrintable(variable));
+ } else {
+ result.push_back(variable);
+ }
+ }
+ }
+#else
+ static const QStringList result = QProcess::systemEnvironment();
+#endif // ifdef Q_OS_WIN
+ return result;
+}
+
bool TestCompiler::runCommand( QString cmdline, bool expectFail )
{
testOutput_.append("Running command: " + cmdline);
QProcess child;
- if (!environment_.empty())
- child.setEnvironment(QProcess::systemEnvironment() + environment_);
+ child.setEnvironment(systemEnvironment() + environment_);
child.start(cmdline);
if (!child.waitForStarted(-1)) {
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
index 6e08e2d02b..166306757c 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
@@ -5,5 +5,3 @@ QT += core-private gui testlib
SOURCES += tst_qfilesystemmodel.cpp
TARGET = tst_qfilesystemmodel
-
-win32:CONFIG += insignificant_test # QTBUG-24291
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index 8724bf63c8..fe374b1e8d 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -51,6 +51,10 @@
#include <QTime>
#include <QStyle>
#include <QtGlobal>
+#include <QTemporaryDir>
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+# include <qt_windows.h> // for SetFileAttributes
+#endif
#define WAITTIME 1000
@@ -69,13 +73,13 @@ class tst_QFileSystemModel : public QObject {
public:
tst_QFileSystemModel();
- virtual ~tst_QFileSystemModel();
public Q_SLOTS:
void init();
void cleanup();
private slots:
+ void initTestCase();
void indexPath();
void rootPath();
@@ -122,29 +126,17 @@ private slots:
void roleNames();
protected:
- bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath());
+ bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList());
private:
QFileSystemModel *model;
QString flatDirTestPath;
+ QTemporaryDir m_tempDir;
};
tst_QFileSystemModel::tst_QFileSystemModel() : model(0)
{
qRegisterMetaType<QModelIndex>("QModelIndex");
-
- QTime midnight(0, 0, 0);
- qsrand(midnight.secsTo(QTime::currentTime()));
- // generating unique temporary directory name
- flatDirTestPath = QDir::temp().path() + '/' + QString("flatdirtest.") + QString::number(qrand());
-}
-
-tst_QFileSystemModel::~tst_QFileSystemModel()
-{
- QString tmp = flatDirTestPath;
- QDir dir(tmp);
- if (dir.exists() && !dir.rmdir(tmp))
- qWarning("failed to remove tmp dir %s", dir.dirName().toAscii().data());
}
void tst_QFileSystemModel::init()
@@ -178,6 +170,12 @@ void tst_QFileSystemModel::cleanup()
}
}
+void tst_QFileSystemModel::initTestCase()
+{
+ QVERIFY(m_tempDir.isValid());
+ flatDirTestPath = m_tempDir.path();
+}
+
void tst_QFileSystemModel::indexPath()
{
#if !defined(Q_OS_WIN)
@@ -367,15 +365,8 @@ void tst_QFileSystemModel::iconProvider()
delete custom;
}
-bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs, const QString &dir)
+bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs)
{
- QDir baseDir(dir);
- if (!baseDir.exists(test_path)) {
- if (!baseDir.mkdir(test_path) && false) {
- qDebug() << "failed to create dir" << test_path;
- return false;
- }
- }
//qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
for (int i = 0; i < initial_dirs.count(); ++i) {
@@ -406,8 +397,21 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi
}
file.close();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (initial_files.at(i)[0] == '.')
- QProcess::execute(QString("attrib +h %1").arg(file.fileName()));
+ if (initial_files.at(i)[0] == '.') {
+ QString hiddenFile = QDir::toNativeSeparators(file.fileName());
+ wchar_t nativeHiddenFile[MAX_PATH];
+ qMemSet(nativeHiddenFile, 0, sizeof(nativeHiddenFile));
+ hiddenFile.toWCharArray(nativeHiddenFile);
+ DWORD currentAttributes = ::GetFileAttributes(nativeHiddenFile);
+ if (currentAttributes == 0xFFFFFFFF) {
+ qErrnoWarning("failed to get file attributes: %s", qPrintable(hiddenFile));
+ return false;
+ }
+ if (!::SetFileAttributes(nativeHiddenFile, currentAttributes | FILE_ATTRIBUTE_HIDDEN)) {
+ qErrnoWarning("failed to set file hidden: %s", qPrintable(hiddenFile));
+ return false;
+ }
+ }
#endif
//qDebug() << test_path + '/' + initial_files.at(i) << (QFile::exists(test_path + '/' + initial_files.at(i)));
}
@@ -818,16 +822,8 @@ void tst_QFileSystemModel::sort()
myModel->d_func()->disableRecursiveSort = true;
#endif
- QDir dir(QDir::tempPath());
- //initialize the randomness
- qsrand(QDateTime::currentDateTime().toTime_t());
- QString tempName = QLatin1String("sortTemp.") + QString::number(qrand());
- dir.mkdir(tempName);
- dir.cd(tempName);
- QTRY_VERIFY(dir.exists());
-
+ QDir dir(flatDirTestPath);
const QString dirPath = dir.absolutePath();
- QVERIFY(dir.exists());
//Create a file that will be at the end when sorting by name (For Mac, the default)
//but if we sort by size descending it will be the first
@@ -889,14 +885,6 @@ void tst_QFileSystemModel::sort()
delete tree;
delete myModel;
-
- dir.setPath(QDir::tempPath());
- dir.cd(tempName);
- tempFile.remove();
- tempFile2.remove();
- dir.cdUp();
- dir.rmdir(tempName);
-
}
void tst_QFileSystemModel::mkdir()
@@ -978,29 +966,17 @@ void tst_QFileSystemModel::drives()
void tst_QFileSystemModel::dirsBeforeFiles()
{
- const QString dirPath = QString("%1/task221717_sortedOrder_test_dir").arg(QDir::tempPath());
- QDir dir(dirPath);
- // clean up from last time
- if (dir.exists()) {
- for (int i = 0; i < 3; ++i) {
- QLatin1Char c('a' + i);
- dir.rmdir(QString("%1-dir").arg(c));
- QFile::remove(dirPath + QString("/%1-file").arg(c));
- }
- dir.rmdir(dirPath);
- }
- QVERIFY(dir.mkpath(dirPath));
- QVERIFY(QDir(dirPath).exists());
+ QDir dir(flatDirTestPath);
for (int i = 0; i < 3; ++i) {
QLatin1Char c('a' + i);
dir.mkdir(QString("%1-dir").arg(c));
- QFile file(dirPath + QString("/%1-file").arg(c));
+ QFile file(flatDirTestPath + QString("/%1-file").arg(c));
file.open(QIODevice::ReadWrite);
file.close();
}
- QModelIndex root = model->setRootPath(dirPath);
+ QModelIndex root = model->setRootPath(flatDirTestPath);
QTest::qWait(1000); // allow model to be notified by the file system watcher
// ensure that no file occurs before a directory
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index 872c13216f..9d9b55cafd 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -562,8 +562,8 @@ void tst_QWizard::setDefaultProperty()
// make sure the data structure is reasonable
for (int i = 0; i < 200000; ++i) {
- wizard.setDefaultProperty("QLineEdit", "x" + QByteArray::number(i), 0);
- wizard.setDefaultProperty("QLabel", "y" + QByteArray::number(i), 0);
+ wizard.setDefaultProperty("QLineEdit", QByteArray("x" + QByteArray::number(i)).constData(), 0);
+ wizard.setDefaultProperty("QLabel", QByteArray("y" + QByteArray::number(i)).constData(), 0);
}
}
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index ca5b992012..843b584ce5 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -3379,10 +3379,11 @@ void tst_QGraphicsProxyWidget::updateAndDelete()
// Update and hide.
proxy->update();
proxy->hide();
- QTRY_COMPARE(view.npaints, 1);
#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-23700", Continue);
+ QEXPECT_FAIL("", "QTBUG-23700", Abort);
#endif
+
+ QTRY_COMPARE(view.npaints, 1);
QCOMPARE(view.paintEventRegion, expectedRegion);
proxy->show();
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index 84dea04c45..af76b1c3c1 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
@@ -69,6 +69,7 @@
#include <QtWidgets/QStyle>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QDesktopWidget>
+#include <private/qgraphicsscene_p.h>
#include <private/qgraphicsview_p.h>
#include "../../../platformquirks.h"
#include "../../../shared/platforminputcontext.h"
@@ -136,6 +137,14 @@ protected:
QEvent::Type spied;
};
+#if defined QT_BUILD_INTERNAL
+class FriendlyGraphicsScene : public QGraphicsScene
+{
+ friend class tst_QGraphicsView;
+ Q_DECLARE_PRIVATE(QGraphicsScene);
+};
+#endif
+
class tst_QGraphicsView : public QObject
{
Q_OBJECT
@@ -167,6 +176,10 @@ private slots:
void ensureVisibleRect();
void fitInView();
void itemsAtPoint();
+#if defined QT_BUILD_INTERNAL
+ void itemsAtPosition_data();
+ void itemsAtPosition();
+#endif
void itemsInRect();
void itemsInRect_cosmeticAdjust_data();
void itemsInRect_cosmeticAdjust();
@@ -1354,6 +1367,55 @@ void tst_QGraphicsView::itemsAtPoint()
QCOMPARE(items.takeFirst()->zValue(), qreal(-1));
}
+#if defined QT_BUILD_INTERNAL
+void tst_QGraphicsView::itemsAtPosition_data()
+{
+ QTest::addColumn<float>("rotation");
+ QTest::addColumn<float>("scale");
+ QTest::addColumn<QPoint>("viewPos");
+ QTest::addColumn<bool>("ignoreTransform");
+ QTest::addColumn<bool>("hit");
+ QTest::newRow("scaled + ignore transform, no hit") << 0.0f << 1000.0f << QPoint(0, 0) << true << false;
+ QTest::newRow("scaled + ignore transform, hit") << 0.0f << 1000.0f << QPoint(100, 100) << true << true;
+ QTest::newRow("rotated + scaled, no hit") << 45.0f << 2.0f << QPoint(90, 90) << false << false;
+ QTest::newRow("rotated + scaled, hit") << 45.0f << 2.0f << QPoint(100, 100) << false << true;
+}
+
+void tst_QGraphicsView::itemsAtPosition()
+{
+ QFETCH(float, rotation);
+ QFETCH(float, scale);
+ QFETCH(QPoint, viewPos);
+ QFETCH(bool, ignoreTransform);
+ QFETCH(bool, hit);
+
+ FriendlyGraphicsScene scene;
+ scene.setSceneRect(QRect(-100, -100, 200, 200));
+ QGraphicsItem *item = scene.addRect(-5, -5, 10, 10);
+
+ if (ignoreTransform)
+ item->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+
+ QGraphicsView view;
+ view.setFrameStyle(QFrame::NoFrame);
+ view.resize(200, 200);
+ view.scale(scale, scale);
+ view.rotate(rotation);
+ view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QPoint screenPos = view.viewport()->mapToGlobal(viewPos);
+ QPointF scenePos = view.mapToScene(viewPos);
+ QGraphicsScenePrivate *viewPrivate = scene.d_func();
+ QList<QGraphicsItem *> items;
+ items = viewPrivate->itemsAtPosition(screenPos, scenePos, view.viewport());
+ QCOMPARE(!items.empty(), hit);
+}
+#endif
+
void tst_QGraphicsView::itemsInRect()
{
QGraphicsScene scene;
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 98872cb2f6..9bbb6aa7f6 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -605,9 +605,6 @@ public slots:
void tst_QApplication::quitOnLastWindowClosed()
{
-#ifdef Q_OS_WIN32
- QSKIP("This test crashes on Windows. Remove skip once the issue causing the crash is fixed (QTBUG-24300).");
-#endif
#ifndef Q_OS_MAC
// Test hangs on Mac OS X, see QTBUG-24319
{
diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
index 6021f90ed4..cff847474c 100644
--- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
+++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
@@ -93,6 +93,7 @@ private slots:
void setValue_data();
void setValue();
void setRepeatAction();
+ void connectedSliders();
private:
void waitUntilTimeElapsed(const QTime& t, int ms);
@@ -1259,5 +1260,17 @@ void tst_QAbstractSlider::setRepeatAction()
QCOMPARE(slider->value(), 115);
}
+void tst_QAbstractSlider::connectedSliders()
+{
+ Slider *slider2 = new Slider(topLevel);
+ connect(slider, SIGNAL(rangeChanged(int, int)), slider2, SLOT(setRange(int, int)));
+ const int sliderlow = 13;
+ const int sliderhigh = 1017;
+ slider->setRange(sliderlow, sliderhigh);
+ QCOMPARE(slider2->minimum(), sliderlow);
+ QCOMPARE(slider2->maximum(), sliderhigh);
+ delete slider2;
+}
+
QTEST_MAIN(tst_QAbstractSlider)
#include "tst_qabstractslider.moc"
diff --git a/tests/benchmarks/corelib/tools/qhash/main.cpp b/tests/benchmarks/corelib/tools/qhash/main.cpp
index 18138cbd47..67396ffd57 100644
--- a/tests/benchmarks/corelib/tools/qhash/main.cpp
+++ b/tests/benchmarks/corelib/tools/qhash/main.cpp
@@ -54,72 +54,91 @@ class tst_QHash : public QObject
Q_OBJECT
private slots:
+ void initTestCase();
void qhash_qt4_data() { data(); }
void qhash_qt4();
- void qhash_faster_data() { data(); }
- void qhash_faster();
void javaString_data() { data(); }
void javaString();
private:
void data();
+
+ QStringList smallFilePaths;
+ QStringList uuids;
+ QStringList dict;
+ QStringList numbers;
};
///////////////////// QHash /////////////////////
-void tst_QHash::data()
-{
- QTest::addColumn<QStringList>("items");
- static QStringList smallFilePaths;
-
- {
- // small list of file paths
- if (smallFilePaths.isEmpty()) {
- QFile smallPathsData("paths_small_data.txt");
- QVERIFY(smallPathsData.open(QIODevice::ReadOnly));
- smallFilePaths = QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n'));
- Q_ASSERT(!smallFilePaths.isEmpty());
- }
+#include <QDebug>
- QTest::newRow("paths-small") << smallFilePaths;
- }
-
- {
- // list of UUIDs
- static QStringList uuids;
- if (uuids.isEmpty()) {
- // guaranteed to be completely random, generated by http://xkcd.com/221/
- QUuid ns = QUuid("{f43d2ef3-2fe9-4563-a6f5-5a0100c2d699}");
- uuids.reserve(smallFilePaths.size());
-
- foreach (const QString &path, smallFilePaths)
- uuids.append(QUuid::createUuidV5(ns, path).toString());
+void tst_QHash::initTestCase()
+{
+ // small list of file paths
+ QFile smallPathsData("paths_small_data.txt");
+ QVERIFY(smallPathsData.open(QIODevice::ReadOnly));
+ smallFilePaths = QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n'));
+ QVERIFY(!smallFilePaths.isEmpty());
+
+ // list of UUIDs
+ // guaranteed to be completely random, generated by http://xkcd.com/221/
+ QUuid ns = QUuid("{f43d2ef3-2fe9-4563-a6f5-5a0100c2d699}");
+ uuids.reserve(smallFilePaths.size());
+
+ foreach (const QString &path, smallFilePaths)
+ uuids.append(QUuid::createUuidV5(ns, path).toString());
+
+
+ // lots of strings with alphabetical characters, vaguely reminiscent of
+ // a dictionary.
+ //
+ // this programatically generates a series like:
+ // AAAAAA
+ // AAAAAB
+ // AAAAAC
+ // ...
+ // AAAAAZ
+ // AAAABZ
+ // ...
+ // AAAAZZ
+ // AAABZZ
+ QByteArray id("AAAAAAA");
+
+ if (dict.isEmpty()) {
+ for (int i = id.length() - 1; i > 0;) {
+ dict.append(id);
+ char c = id.at(i);
+ id[i] = ++c;
+
+ if (c == 'Z') {
+ // wrap to next digit
+ i--;
+ id[i] = 'A';
+ }
}
-
- QTest::newRow("uuids-list") << uuids;
}
+ // string versions of numbers.
+ for (int i = 5000000; i < 5005001; ++i)
+ numbers.append(QString::number(i));
}
-void tst_QHash::qhash_qt4()
+void tst_QHash::data()
{
- QFETCH(QStringList, items);
- QStringList realitems = items; // for copy/paste ease between benchmarks
- QHash<QString, int> hash;
-
- QBENCHMARK {
- for (int i = 0, n = realitems.size(); i != n; ++i) {
- hash[realitems.at(i)] = i;
- }
- }
+ QTest::addColumn<QStringList>("items");
+ QTest::newRow("paths-small") << smallFilePaths;
+ QTest::newRow("uuids-list") << uuids;
+ QTest::newRow("dictionary") << dict;
+ QTest::newRow("numbers") << numbers;
}
-void tst_QHash::qhash_faster()
+void tst_QHash::qhash_qt4()
{
QFETCH(QStringList, items);
- QHash<String, int> hash;
+ QHash<Qt4String, int> hash;
- QList<String> realitems;
+ QList<Qt4String> realitems;
foreach (const QString &s, items)
realitems.append(s);
diff --git a/tests/benchmarks/corelib/tools/qhash/main.h b/tests/benchmarks/corelib/tools/qhash/main.h
index c4cf94e190..a865eaf7a6 100644
--- a/tests/benchmarks/corelib/tools/qhash/main.h
+++ b/tests/benchmarks/corelib/tools/qhash/main.h
@@ -41,14 +41,14 @@
#include <QString>
-struct String : QString
+struct Qt4String : QString
{
- String() {}
- String(const QString &s) : QString(s) {}
+ Qt4String() {}
+ Qt4String(const QString &s) : QString(s) {}
};
QT_BEGIN_NAMESPACE
-uint qHash(const String &);
+uint qHash(const Qt4String &);
QT_END_NAMESPACE
diff --git a/tests/benchmarks/corelib/tools/qhash/outofline.cpp b/tests/benchmarks/corelib/tools/qhash/outofline.cpp
index 162c604a35..75d99f96f8 100644
--- a/tests/benchmarks/corelib/tools/qhash/outofline.cpp
+++ b/tests/benchmarks/corelib/tools/qhash/outofline.cpp
@@ -41,49 +41,19 @@
#include "main.h"
-static void doHash(const unsigned short *p, uint &h)
-{
-#if 1
- // Copied from static uint hash(const QChar *p, int n).
- // Possibly not the cheapest way.
- h = (h << 4) + (*p++);
- h ^= (h & 0xf0000000) >> 23;
- h &= 0x0fffffff;
-
- h = (h << 4) + (*p++);
- h ^= (h & 0xf0000000) >> 23;
- h &= 0x0fffffff;
-
- h = (h << 4) + (*p++);
- h ^= (h & 0xf0000000) >> 23;
- h &= 0x0fffffff;
-
- h = (h << 4) + (*p++);
- h ^= (h & 0xf0000000) >> 23;
- h &= 0x0fffffff;
-#else
- // Faster, but probably less spread.
- h ^= *(unsigned int *)p;
-#endif
-}
-
QT_BEGIN_NAMESPACE
-uint qHash(const String &str)
+uint qHash(const Qt4String &str)
{
- const unsigned short *p = (unsigned short *)str.constData();
- const int s = str.size();
- switch (s) {
- case 0: return 0;
- case 1: return *p;
- case 2: return *(unsigned int *)p;
- case 3: return (*(unsigned int *)p) ^ *(p + 2);
- //case 3: return (*p << 11) + (*(p + 1) << 22) + *(p + 2);
- }
+ int n = str.length();
+ const QChar *p = str.unicode();
uint h = 0;
- doHash(p, h);
- doHash(p + s / 2 - 2, h);
- doHash(p + s - 4, h);
+
+ while (n--) {
+ h = (h << 4) + (*p++).unicode();
+ h ^= (h & 0xf0000000) >> 23;
+ h &= 0x0fffffff;
+ }
return h;
}
diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32
index 92de55f137..d2193d7619 100644
--- a/tools/configure/Makefile.win32
+++ b/tools/configure/Makefile.win32
@@ -65,7 +65,8 @@ OBJECTS = \
qxmlutils.obj \
quuid.obj \
qcryptographichash.obj \
- registry.obj
+ registry.obj \
+ configure_pch.obj
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 504728abc8..a586821bdc 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -1158,11 +1158,7 @@ void Configure::parseCmdLine()
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
} else if (dictionary[ "QMAKESPEC" ] == QString("win32-g++")) {
if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "mingw32-make";
- if (Environment::detectExecutable("sh.exe")) {
- dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++-sh";
- } else {
- dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++";
- }
+ dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++";
} else {
if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "make";
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
@@ -2681,6 +2677,29 @@ QString Configure::addDefine(QString def)
}
#if !defined(EVAL)
+bool Configure::copySpec(const char *name, const char *pfx, const QString &spec)
+{
+ // Copy configured mkspec to default directory, but remove the old one first, if there is any
+ QString defSpec = buildPath + "/mkspecs/" + name;
+ QFileInfo defSpecInfo(defSpec);
+ if (defSpecInfo.exists()) {
+ if (!Environment::rmdir(defSpec)) {
+ cout << "Couldn't update default " << pfx << "mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
+ dictionary["DONE"] = "error";
+ return false;
+ }
+ }
+
+ QString pltSpec = sourcePath + "/mkspecs/" + spec;
+ QString includeSpec = buildPath + "/mkspecs/" + spec;
+ if (!Environment::cpdir(pltSpec, defSpec, includeSpec)) {
+ cout << "Couldn't update default " << pfx << "mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
+ dictionary["DONE"] = "error";
+ return false;
+ }
+ return true;
+}
+
void Configure::generateConfigfiles()
{
QDir(buildPath).mkpath("src/corelib/global");
@@ -2728,10 +2747,6 @@ void Configure::generateConfigfiles()
tmpStream << "#define QT_BUILD_INTERNAL" << endl;
tmpStream << endl;
}
- tmpStream << "/* Machine byte-order */" << endl;
- tmpStream << "#define Q_BIG_ENDIAN 4321" << endl;
- tmpStream << "#define Q_LITTLE_ENDIAN 1234" << endl;
- tmpStream << "#define Q_BYTE_ORDER Q_LITTLE_ENDIAN" << endl;
if (dictionary[ "QPA" ] == "yes")
tmpStream << endl << "#define Q_WS_QPA" << endl;
@@ -2864,25 +2879,9 @@ void Configure::generateConfigfiles()
tmpFile.close();
}
- // Copy configured mkspec to default directory, but remove the old one first, if there is any
- QString defSpec = buildPath + "/mkspecs/default";
- QFileInfo defSpecInfo(defSpec);
- if (defSpecInfo.exists()) {
- if (!Environment::rmdir(defSpec)) {
- cout << "Couldn't update default mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
- dictionary["DONE"] = "error";
- return;
- }
- }
-
QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
- QString pltSpec = sourcePath + "/mkspecs/" + spec;
- QString includeSpec = buildPath + "/mkspecs/" + spec;
- if (!Environment::cpdir(pltSpec, defSpec, includeSpec)) {
- cout << "Couldn't update default mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
- dictionary["DONE"] = "error";
+ if (!copySpec("default", "", spec))
return;
- }
// Generate the new qconfig.cpp file
QDir(buildPath).mkpath("src/corelib/global");
diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h
index c3838fb139..58544b5041 100644
--- a/tools/configure/configureapp.h
+++ b/tools/configure/configureapp.h
@@ -79,6 +79,7 @@ public:
void generateMakefiles();
void appendMakeItem(int inList, const QString &item);
#if !defined(EVAL)
+ bool copySpec(const char *name, const char *pfx, const QString &spec);
void generateConfigfiles();
#endif
void showSummary();